0

I have this html table:

<table id="sanityTestsTable" border="1">
<tbody>
<tr>
   <th>ID</th>
   <th>Sanity Check</th>
   <th>Result</th>
</tr>
<tr>
   <td>1</td>
   <td><input name="sanityItem" size="20" maxlength="255" type="text"></td>
   <td>Not available yet</td>
</tr>
<tr>
   <td>2</td>
   <td><input name="sanityItem" size="20" maxlength="255" type="text"></td>
   <td>Not available yet</td>
</tr>
</tbody></table>

Whenever the user enters anything in input field I like to add new empty input field. This works fine with jQuery:

$("input[name='sanityItem']").change(function(){
   var emptyRows = 0;
   $("#sanityTestsTable tbody > tr td:nth-child(2) input").each(function(){ 
      if ( $(this).val() == "" ) 
         emptyRows++; 
   });      
   if ( emptyRows < 2 ) {
      $("#sanityTestsTable tbody > tr").each(function(index){
         if ( $(this).is($("#sanityTestsTable tbody > tr:last")) ) {
            var txt1 = "<tr><td>" + (index + 1) +"</td><td><input name=\"sanityItem\" size=\"20\" maxlength=\"255\" type=\"text\"></td><td>Not available yet</td></tr>";  
            $(txt1).insertAfter(this);
            var lastRow = $("#sanityTestsTable tbody > tr:last");                
            // This does not work:
            lastRow.on("change", null, lastRow, $("input[name='sanityItem']").change() );
         }
      });
   }
});

Howver the change event is not caught on new inserted rows. New rows are only added when initial rows 1 or 2 are edited. When you enter text into new row (e.g. 3) then I like further empty rows to appended. What is the proper usage of .on() call? I also tried with .bind() but no success either.

After many "try and errors" I got it:

function changeHandler() {
        var emptyRows = 0;
        $("#sanityTestsTable tbody > tr td:nth-child(2) input").each(function(){ if ( $(this).val() == "" ) emptyRows++; });        
        if ( emptyRows < 2 ) {
            $("#sanityTestsTable tbody > tr").each(function(index){
                if ( $(this).is($("#sanityTestsTable tbody > tr:last")) ) {
                    var txt1 = "<tr><td>" + (index + 1) +"</td><td><input name=\"sanityItem\" size=\"20\" maxlength=\"255\" type=\"text\"></td><td>Not available yet</td></tr>";  
                    $(txt1).insertAfter(this);
                    // Attach change handler to last row
                    $("#sanityTestsTable tbody > tr:last td:nth-child(2) input").on("change", function() { changeHandler() });
                }
            });
        }

}

$("input[name='sanityItem']").change( function() {changeHandler()} );
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Wernfried Domscheit
  • 54,457
  • 9
  • 76
  • 110
  • I had a look at given answer. However, it has to call `change` function on `change` event. How to refer to `$("input[name='sanityItem']").change` recursively? – Wernfried Domscheit Jan 14 '16 at 10:16
  • Use `$("#sanityTestsTable").on("change", "input[name='sanityItem']", function() { //do something here })` – mylee Jan 14 '16 at 10:24
  • the `do something here` is exactly my problem: How to refer to the original event handler `$("input[name='sanityItem']").change(function(){...}`? – Wernfried Domscheit Jan 14 '16 at 10:31
  • What i meant was to replace your original event listener with this one which is attached to the common parents for all the dynamic inputs – mylee Jan 14 '16 at 10:35
  • Maybe I am stupid, I don't have much experience with jQuery or JavaScript. If the solution appears to be so easy, please simply provide it to me - I don't get it. – Wernfried Domscheit Jan 14 '16 at 10:46
  • Just simply like this: `$("#sanityTestsTable").on("change", "input[name='sanityItem']", function() { var emptyRows = 0; ......... })` – mylee Jan 14 '16 at 10:48
  • Still not working, see latest update - it is **recursive**. I cannot write the code infinite times. – Wernfried Domscheit Jan 14 '16 at 11:01
  • Look carefully at this line `$("#sanityTestsTable").on("change", "input[name='sanityItem']", function() { changeHandler(); })`, which binds the event to the common parent (table) of dynamic inputs, and compare it to your existing code, which bind to only the two inputs which exists at the time of execution – mylee Jan 14 '16 at 11:10
  • Please, tell me what version of jquery do you use. The approach you should use called: Event delegation. It is when you add event listener to the some parent element, that is already in the dom, and iterate through it's children, and if match will be find than call callback. So, you just pass to the .on method three parameters parentSelector, childSelector and callback. Your code is almost correct. Just pass three parameters to the .on() method – Sergii Shvager Jan 14 '16 at 11:17
  • jQuery version 1.12.0 – Wernfried Domscheit Jan 14 '16 at 12:10
  • Does `$("#sanityTestsTable tbody > tr:last td:nth-child(2) input").on("change", function() { changeHandler() });` word as well? – Wernfried Domscheit Jan 14 '16 at 12:49

0 Answers0