0

I have an input form that when the add button is clicked, it submits the current line of data and then adds a new row of input fields for more data entry. When I click the add button, it will post the first input data into the database and create a new row. However when I try to submit the second row, nothing happens. The data isn't submitted and another row isnt added.

This is my jquery click function

$('#addRow').click(function(e) {
        const cloneRow = $('#tableData tbody tr').first();
        e.preventDefault();
        let data = {
         project_id: $(".project_id").last().val(),
         imp_or_ann: $(".imp_or_ann").last().val(),
         category: $(".category").last().val(),
         cost: $(".cost").last().val(),
         hours: $(".hours").last().val()
    }
        $.ajax({
            url: '/costs_hours',
            type: 'POST',
            data: data
        }).then(
            cloneRow.clone().appendTo('#tableData tbody').find(".cost, .hours").val(''),
            $("#next").removeAttr('disabled'),
            $("#link").attr('href', '/fundings')
        )

    })

This is my input form

 <table id="tableData" class="table text-light text-center mt-3">
                    <thead>
                        <tr>
                            <th scope="col">Project ID</th>
                            <th scope="col">Implementation or Annual</th>
                            <th scope="col">Category</th>
                            <th scope="col">Costs</th>
                            <th scope="col">Hours</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>
                                <div class="input-group mb-3">
                                    <input name="project_id" type="text" class="form-control project_id">
                                </div>
                            </td>
                            <td>
                                <div class="input-group mb-3">
                                    <div class="input-group mb-3">
                                        <select name="imp_or_ann" class="form-select imp_or_ann"
                                            id="inputGroupSelect01">
                                            <option disabled selected>Choose...</option>
                                            <option>Implementation</option>
                                            <option>Annual</option>
                                        </select>
                                    </div>
                                </div>
                            </td>
                            <td>
                                <div class="input-group mb-3">
                                    <div class="input-group mb-3">
                                        <select name="category" class="form-select category" id="inputGroupSelect01">
                                            <option disabled selected>Choose...</option>
                                            <option>EMO</option>
                                            <option>Analysts</option>
                                            <option>Maintenance</option>
                                            <option>ETS</option>
                                            <option>BOT</option>
                                            <option>OtherUT</option>
                                            <option>Materials</option>
                                            <option>Non-UT Contract</option>
                                            <option>Contingency</option>
                                        </select>
                                    </div>
                                </div>
                            </td>
                            <td>
                                <div class="input-group mb-3">
                                    <input name="cost" type="text" class="cost form-control">
                                </div>
                            </td>
                            <td>
                                <div class="input-group mb-3">
                                    <input name="hours" type="text" class="hours form-control">
                                </div>
                            </td>
                            <td>
                                <button id='addRow' type="button" style="background-color: #bf5700;"
                                    class="btn btn-warning text-light"><i
                                        class="fas fa-plus-circle"></i>&nbsp;Add</button>
                            </td>
                        </tr>
                    </tbody>
                </table>

I want the button to stay in the so the use knows they have to click the add button to add that piece of data. But this currently only works for the first data input. When the second row is added, The button doesnt work, I cant submit data and another row isnt created. Any advice is greatly appreciated!

Matthew
  • 253
  • 1
  • 15

2 Answers2

1

$('#addRow') is evaluated once, when the JS code is executed.

When you clone and add new row, you are effectively created a new (and different!) element with id="addRow". THAT element does not have a handler listening for click events.

Instead, you need to put the listener on something that does not change, for example #tableData, using the jquery $.on():

   $('#tableData').on('click', '.addRow', function(e){
      ...
   });

This way, the element listening is #tableData, which gets clicks and then checks to see if the click originated on something matching .addRow. Your actual function doesn't need to change.

However, you will need to change your add button from id="addRow" to class="addRow", (or use name attribute or anything else) so you don't have multiple elements with same ID in the DOM.

pbuck
  • 4,291
  • 2
  • 24
  • 36
0

Well, you were setting the same ID for multiple objects which is problematic, but what you really needed was to set the listener on a static parent (I used tableData). I changed your button ID to a class, so it could apply to all add buttons.

Your listener was set to scan the page for button#addRow and attach a listener. Then you create a new instance of the button, but the listener setup had already fired and wasn't aware of the newly created instance. Instead, set the listener on a static parent. The event is on with arguments of click to detect the click and button.addRow to specify which element to focus the listener on.

$('#tableData').on('click', 'button.addRow', function(e) {
  const cloneRow = $('#tableData tbody tr').first();
  e.preventDefault();
  let data = {
    project_id: $(".project_id").last().val(),
    imp_or_ann: $(".imp_or_ann").last().val(),
    category: $(".category").last().val(),
    cost: $(".cost").last().val(),
    hours: $(".hours").last().val()
  }
  $.ajax({
    url: '/costs_hours',
    type: 'POST',
    data: data
  }).then(
    cloneRow.clone().appendTo('#tableData tbody').find(".cost, .hours").val(''),
    $("#next").removeAttr('disabled'),
    $("#link").attr('href', '/fundings')
  )

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tableData" class="table text-light text-center mt-3">
  <thead>
    <tr>
      <th scope="col">Project ID</th>
      <th scope="col">Implementation or Annual</th>
      <th scope="col">Category</th>
      <th scope="col">Costs</th>
      <th scope="col">Hours</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        <div class="input-group mb-3">
          <input name="project_id" type="text" class="form-control project_id">
        </div>
      </td>
      <td>
        <div class="input-group mb-3">
          <div class="input-group mb-3">
            <select name="imp_or_ann" class="form-select imp_or_ann" id="inputGroupSelect01">
              <option disabled selected>Choose...</option>
              <option>Implementation</option>
              <option>Annual</option>
            </select>
          </div>
        </div>
      </td>
      <td>
        <div class="input-group mb-3">
          <div class="input-group mb-3">
            <select name="category" class="form-select category" id="inputGroupSelect01">
              <option disabled selected>Choose...</option>
              <option>EMO</option>
              <option>Analysts</option>
              <option>Maintenance</option>
              <option>ETS</option>
              <option>BOT</option>
              <option>OtherUT</option>
              <option>Materials</option>
              <option>Non-UT Contract</option>
              <option>Contingency</option>
            </select>
          </div>
        </div>
      </td>
      <td>
        <div class="input-group mb-3">
          <input name="cost" type="text" class="cost form-control">
        </div>
      </td>
      <td>
        <div class="input-group mb-3">
          <input name="hours" type="text" class="hours form-control">
        </div>
      </td>
      <td>
        <button type="button" style="background-color: #bf5700;" class="addRow btn btn-warning text-light"><i
                                        class="fas fa-plus-circle"></i>&nbsp;Add</button>
      </td>
    </tr>
  </tbody>
</table>
Kinglish
  • 23,358
  • 3
  • 22
  • 43