Auto calculate difference of year and month using javascript in a dynamic table

The code below shows the HTML and the javascript of my code, I’ve created a dynamic table which will allow the user to add and remove the row of table dynamically. What I’m trying to do now is the auto calculation of two date (Month and Year only). The duration table are not responsive at all after I’ve select the month and year between the date.

Javascript

<script src="https://code.jquery.com/jquery-3.5.0.js"></script>
<script type="text/javascript">
var h = 0;
    function history() {
    h++;
    var copyContent= "<div class='row' name='rows' style='margin-top:-20px;'>";
        copyContent= "<tr><td><input class='tableBody' type='month' id='from"+h+"' name='from[]' autocomplete='off' required></td>";
            copyContent += "<td><input class='tableBody' type='month' id='to"+h+"' name='to[]' autocomplete='off' required></td>";
            copyContent += "<td><input class='tableBody' type='text' id='duration"+h+"' name='duration[]' autocomplete='off' required></td>";
            copyContent += "<td><a href='javascript:void(0);' class='remove' style='cursor:pointer'><i class='material-icons' title='Delete item'>remove_circle_outline</i></a></td></tr></div>";
            $('#tbl_history').append(copyContent);

            document.getElementById("h").value = h;
        }
        
//duration calculation
$('#from[]').change(function() {

    ToDate.min = document.getElementById('from0').value;
    var start = new Date(document.getElementById('from0').value);
    var end = new Date(document.getElementById('to').value);
    var duration = new Date();

    var different = end.getTime() - start.getTime();
    // duration = (different/(1000*60*60*24))+1;
    duration = (new Date(start), new Date(end));
    document.getElementById('duration').value = duration;


        document.getElementById('duration').value = (start, end);
    
});


$('#ToDate').change(function() {
    var start = new Date(document.getElementById('from').value);
    var end = new Date(document.getElementById('to').value);
    var duration = new Date();

    var different = end.getTime() - start.getTime();
    // duration = (different/(1000*60*60*24))+1;
    duration = (new Date(start), new Date(end));
    document.getElementById('duration').value = duration;

        document.getElementById('duration').value = (start, end);
    
});



});

       
</script>

HTML

<table id="tbl_history" style="margin-top:25px;margin-bottom:25px;">
    <tr class="tableTitle">
        <th><center>From</th>
        <th><center>To</th>
        <th style="width:150px;"><center>Duration</th>                                                                                       
    </tr>
<br/>                                               
<tr>
    <td><input class="tableBody" type="month" id="from0" name="from[]" autocomplete="off" required></td>
    <td><input class="tableBody" type="month" id="to0" name="to[]" autocomplete="off" required></td>
    <td><input class="tableBody" type="text" id="duration0" name="duration[]" autocomplete="off" required></td>
</tr>                                                                                           </table>
<div style="margin-right:-1200px">
   <a onclick="history()" style="cursor:pointer"><i class="material-icons" title="Add item">add_circle_outline</i></a> 
</div> 
<input name="h" type="text" id="h" readonly hidden> 

Answer

As I do not use jQuery I offer instead a vanilla Javascript alternative that uses delegated event listeners to process the various events which we are interested in – namely the change event of the date fields and possibly the click event of the removal hyperlink.

/*
  global variable that will store values from all input elements
  of type "month"
*/
var rows={};


/*
  Utility function that works it's way UP the DOM
  tree until a node of a particular type is found
  or returns false if not found. Useful to find a
  particular parent node.
*/
const getparent=(e,tag)=>{
  let n=e.target;
  while( n.tagName.toUpperCase()!=tag.toUpperCase() ){
    if( n.nodeName==='BODY' )return false;
    n=n.parentNode;
  }
  return n;
};

/*
  rudimentary date difference calculations
  - crude but illustrative. Will return 
  the number of years, months & total days
*/
const datedifference=(d1,d2)=>{
  return {
    y:( d2.getFullYear() - d1.getFullYear() ),
    m:( d2.getMonth() - d1.getMonth() ),
    d:( Math.abs( ( d2 - d1 ) / ( 1000 * 60 * 60 * 24 ) ) )
  }
};





/*
  Bind a "delegated" event listener to the table itself but
  process only events that satisfy the given criteria - ie:
  input elements of type "month" will fire the event handler
  code. Any other source will be disregarded.
*/
document.getElementById('tbl_history').addEventListener('change',function(e){
  if( e.target!=e.currentTarget && e.target.nodeType==1 && e.target.tagName=='INPUT' ){
    /*
      find the table row - it has the dataset attribute that makes
      working with the `rows` object easier.
    */
    let parent=getparent(e,'tr');
    
    /*
      Find the input element that will display 
      the calculated date difference
    */
    let duration=parent.querySelector('input[type="text"]');
    
    /*
      find the row index
    */
    let row=parent.dataset.row;
    
    /*
      create new object per table row
      and store input value
    */
    if( !rows.hasOwnProperty( row ) )rows[ row ]={};
    rows[ row ][ e.target.name ]=e.target.value;

    /*
      Once both input elements have a value we
      can do the date difference calculations
      and display the value.
    */
    if( Object.keys( rows[ row ] ).length==2 ){
      let keys=Object.keys( rows[ row ] );
      let d1=new Date( rows[ row ][ keys[0] ] );
      let d2=new Date( rows[ row ][ keys[1] ] );

      let obj=datedifference(d1,d2);
      duration.value=[ obj.y+'yrs', obj.m+'months' ].join(', ');
    }
  }
});
document.getElementById('tbl_history').addEventListener('click',function(e){
  if( e.target!=e.currentTarget && e.target.nodeType==1 && e.target.tagName=='I' ){
    let p=getparent(e,'tr');
      p.parentNode.removeChild(p);
  }
});




/*
  Essentially the same except for the removal of ID attributes, 
  the removal of the incorrect DIV elements and using template 
  literals rather than string concatenation. Oh and no jQuery.
*/
var h=0;
function history() {
  h++;
  var html = `
  <tr data-row='${h}'>
    <td><input class='tableBody' type='month' name='from[]' autocomplete='off' required /></td>
    <td><input class='tableBody' type='month' name='to[]' autocomplete='off' required /></td>
    <td><input class='tableBody' type='text' name='duration[]' autocomplete='off' required /></td>
    <td>
      <a href='javascript:void(0);' class='remove' style='cursor:pointer'>
        <i class='material-icons' title='Delete item'>remove_circle_outline</i>
      </a>
    </td>
  </tr>`;
  
  document.getElementById('tbl_history').insertAdjacentHTML('beforeend',html);
  document.getElementById('h').value=h;
}
<table id='tbl_history' style='margin-top:25px;margin-bottom:25px;'>
  <tr class='tableTitle'>
    <th><center>From</th>
    <th><center>To</th>
    <th style='width:150px;'><center>Duration</th>                                                                                       
  </tr>
  <!--
  
    do not add <br /> tags within the table body!!
    Removed ID attributes from input elements and
    added data-row attribute to table row element.
    
  -->
  <tr data-row='0'>
    <td><input class='tableBody' type='month' name='from[]' autocomplete='off' required /></td>
    <td><input class='tableBody' type='month' name='to[]' autocomplete='off' required /></td>
    <td><input class='tableBody' type='text' name='duration[]' autocomplete='off' required /></td>
  </tr>
</table>

<div style='margin-right:-1200px'>
   <a onclick='history()' style='cursor:pointer'>
  <i class='material-icons' title='Add item'>add_circle_outline</i>
   </a> 
</div>

<input name='h' type='text' id='h' value=0 readonly hidden />