-2

I have the following table that actually encapsulates a dynamic form. I need to select the specific .check class in Rmk column of the table and print Hello World on blur() event for any input field of that row. enter image description here It absolutely works fine until I create new rows. When I create a new row, it cannot select the class. Any help?

function myCreateFunction() {
    var table = document.getElementById("myTable");
   var c = document.getElementById("myTable").rows.length;
 
  var row = table.insertRow(c);
  var cell1 = row.insertCell(0);
  var cell2 = row.insertCell(1);
  cell1.innerHTML = "<input type='text' class='lat' name='lat[]' /><span class='availability'></span>";
  cell2.innerHTML = "<input type='text' class='long' name='long[]' /><span id='availability'></span>";
    
}
function myDeleteFunction() {
 var cd = document.getElementById("myTable").rows.length;
 if(cd<=3)
 {
  //do nothing
 }
 else{
  document.getElementById("myTable").deleteRow(cd-1);
 }
}

$('input').on('blur', function() {
    var t = $(this);
    t.closest('tr').find('.check').text('Hello World');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="form-handler.php" method="POST">
<table id="myTable">
        <tr>
            <th class="theader"> Lat </th>
            <th class="theader"> Long </th>
            <th class="theader"> Rmk </th>
        </tr>
        <tr>
            <td class="troe"> <input type='text' class='lat' name='lat[]' /> </td>
            <td class="trow"> <input type='text' class='long' name='long[]' /> </td>
            <td class="trow">
            <span class="check"></span> 
            </td>
        </tr>
        <tr>
            <td class="troe"> <input type='text' class='lat' name='lat[]' /> </td>
            <td class="trow"> <input type='text' class='long' name='long[]' /> </td>
            <td class="trow">
            <span class="check"></span> 
            </td>
        </tr>
        <tr>
            <td class="troe"> <input type='text' class='lat' name='lat[]' /> </td>
            <td class="trow"> <input type='text' class='long' name='long[]' /> </td>
            <td class="trow">
            <span class="check"></span> 
            </td>
        </tr>
    </table>
    <button class="myBtn" type="submit" id='submit' name="submit" value="submit">submit</button>
</form>
<br/>
<button onclick="myCreateFunction()">Create New Row </button>
<button onclick="myDeleteFunction()">Delete Row</button>
  • Possible duplicate of [Event binding on dynamically created elements?](https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – Taplar Sep 07 '18 at 15:03
  • Sorry, it's not.. It doesn't match my problem specifically. :( – Sophia Jose Sep 07 '18 at 15:07
  • It does indeed. You are creating new input elements, and you are expecting the binding that you created for the pre-existing inputs to also work on the new dynamically created inputs. That is the very reason delegate event bindings (mentioned in the duplicate) exist. Also extra Ref. http://learn.jquery.com/events/event-delegation/ – Taplar Sep 07 '18 at 15:08
  • okay, may be that is, but as I've little knowledge in event binding, I still cant relate it to my problem. Would you pls correct my snippet in an answer? – Sophia Jose Sep 07 '18 at 15:15
  • Take some time to read the duplicate post, and the Ref I provided in my comment. I could just give it to you, but being able to read documentation is an important aspect of development. Don't be scared to just try things from documentation. – Taplar Sep 07 '18 at 15:16

2 Answers2

0

Part of the answer is, as suggested, related to the Event binding on dynamically created elements, and I totally agree with who wrote the comments to carefully read that and the official documentation about about event delegation.

Anyway this is not the complete answer, because you need to correct your code when you dynamically create the new row. Basically, you are not creating the third td element with the respective <span>, with the class check, that you use in the blur event.

At the end, it's something like this:

function myCreateFunction() {
    var table = document.getElementById("myTable");
   var c = document.getElementById("myTable").rows.length;
 
  var row = table.insertRow(c);
  var cell1 = row.insertCell(0);
  var cell2 = row.insertCell(1);
  var cell3 = row.insertCell(2);
  cell1.innerHTML = "<input type='text' class='lat' name='lat[]' /><span class='availability'></span>";
  cell2.innerHTML = "<input type='text' class='long' name='long[]' /><span id='availability'></span>";
  cell3.innerHTML = "<span class='check'></span>";
    
}
function myDeleteFunction() {
 var cd = document.getElementById("myTable").rows.length;
 if(cd<=3)
 {
  //do nothing
 }
 else{
  document.getElementById("myTable").deleteRow(cd-1);
 }
}

$(document).on('blur', '#myTable input', function() {
    var t = $(this);
    t.closest('tr').find('.check').text('Hello World');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="form-handler.php" method="POST">
<table id="myTable">
        <tr>
            <th class="theader"> Lat </th>
            <th class="theader"> Long </th>
            <th class="theader"> Rmk </th>
        </tr>
        <tr>
            <td class="troe"> <input type='text' class='lat' name='lat[]' /> </td>
            <td class="trow"> <input type='text' class='long' name='long[]' /> </td>
            <td class="trow">
            <span class="check"></span> 
            </td>
        </tr>
        <tr>
            <td class="troe"> <input type='text' class='lat' name='lat[]' /> </td>
            <td class="trow"> <input type='text' class='long' name='long[]' /> </td>
            <td class="trow">
            <span class="check"></span> 
            </td>
        </tr>
        <tr>
            <td class="troe"> <input type='text' class='lat' name='lat[]' /> </td>
            <td class="trow"> <input type='text' class='long' name='long[]' /> </td>
            <td class="trow">
            <span class="check"></span> 
            </td>
        </tr>
    </table>
    <button class="myBtn" type="submit" id='submit' name="submit" value="submit">submit</button>
</form>
<br/>
<button onclick="myCreateFunction()">Create New Row </button>
<button onclick="myDeleteFunction()">Delete Row</button>
Lorenzo S
  • 1,397
  • 13
  • 25
0

I would suggest doing it a bit easier:

Make a little hidden snippet with the rows, makes it a bit easier to work with.

<table id="table-row-source" style="display:none">
    <tr>
        <td class="troe"> <input type='text' class='lat' name='lat[]' /> </td>
        <td class="trow"> <input type='text' class='long' name='long[]' /> </td>
        <td class="trow">
            <span class="check"></span>
        </td>
    </tr>
</table>

Which would turn your myCreateFunction into this:

function myCreateFunction() {
    $("#myTable").append($('#table-row-source').html());
    InitializeInputEventBlur();
}

Then I would turn the Blur Event handler into a function that is called on document ready and every time you create a new row to restore the bonds.

function InitializeInputEventBlur() {
    $('input').on('blur', function () {
        var t = $(this);
        t.closest('tr').find('.check').text('Hello World');
    });
}

$(document).ready(function () {
    InitializeInputEventBlur();
});
Jan Andersen
  • 773
  • 1
  • 6
  • 13