javascriptjqueryjquery-ui-tabs

Why is the content being appended to the wrong dynamically-generated tab?


I am trying to create jQuery Tabs dynamically. It should work so that every time I click on "Generate" Multiplication table button a new Tab should be created and a table with the current data parameters will be displayed in this tab.

Currently, the first tab stores all the tables, and the subsequent tabs do not store anything: enter image description here

How can I make the first tab store only the first table and the second tab the next table and so on?

$( document ).ready(function() {

  var tabs = [];
  
//Function to generate a multiplication table based on user's range input.
function generateTable(minCol, maxCol, minRow, maxRow) {
  let tabsList = document.getElementById("tabsList");
  let tableTabs = document.getElementById("tableTabs");

  let tabObject = { 
    name: tabs.length, 
    minCol: minCol,
    maxCol: maxCol,
    minRow: minRow,
    maxRow: maxRow
  };
  tabs.push(tabObject);

  let listItem = document.createElement("li");
  let anchor = document.createElement("a");
  anchor.href = `#tab-${tabs.length-1}`;
  anchor.innerText = `tab-${tabs.length-1}`;
  listItem.appendChild(anchor);
  tabsList.appendChild(listItem);
  listItem.classList.add("ui-tabs-tab");

  let tableDiv = document.createElement("div");
  tableDiv.id = `tab-${tabs.length-1}`;
  tableTabs.appendChild(tableDiv);

  var error = document.getElementById("message");

  var table = document.createElement("table");
  var result = "";
  //creating a multTable
  for(var i=minRow; i<=maxRow;i++)
  {
      if(i==minRow)
      {
        result += "<tr>";
        result += "<th>&times;</th>";
      }

      for(var j=minCol; j<=maxCol; j++)
      {
          if(i==minRow || j==minCol)
          {
            if(i==minRow)
              result += "<th>" + j + "</th>";
            else
              result += "<td>"+ (i-1)*j + "</td>";
          }
          else
            result += "<td>"+ (i-1)*j + "</td>";
      }
        result += "</tr>";
        result += "<tr>";
        result += "<th>" + i + "</th>";
        if(i==maxRow)
        {
          for(var j=minCol; j<=maxCol; j++)
          {
            result += "<td>"+ i*j + "</td>";
          }
        }
    }
  //printing the table
  table.innerHTML=result;
  tableDiv.appendChild(table);
  $("#tableTabs").tabs( { "active" : tabs.length-1});
  return false;
}

//Function to validate user's input
$(function() {
  $("#inputForm").submit(function(e) {
    e.preventDefault();
  }).validate({
      submitHandler: function(form) {
      var minCol = parseInt(document.getElementById("minCol").value);
      var maxCol = parseInt(document.getElementById("maxCol").value);
      var minRow = parseInt(document.getElementById("minRow").value);
      var maxRow = parseInt(document.getElementById("maxRow").value);
      generateTable(minCol, maxCol, minRow, maxRow);
      return false;
    }
  });//end validate

});//end function

});
html {
  background-color: #9FA5FF;
  height: 100%;
}

body {
  background-color: #E2E3FF;
  margin: 0 auto;
  width: 70%;
}

h2 {
  padding-top: 20px;
  padding-bottom: 20px;
  text-align: center;
  background-color: #c68de2;
}

h6 {
  text-align: center;
  margin-bottom: 0px;
}

.purple-background {
  background-color:#c68de2;
}

.black {
  color:#000000;
}

.inputfield{
  height:30px;
}
.containerInput {
  padding-left: 0px;
  padding-right: 0px;
}

.container {
  padding: 20px 0;
  overflow: scroll;
  height: 400px;
}

#multTable {
  margin: auto;
}

#multTable td, th {
  width: 50px;
  font-size: 20px;
  border: 1px solid blue;
}

#multTable td:nth-child(even) {
  background-color: #ffffff;
}

#multTable th {
  background-color: #9FA5FF;
}

#message p{
  color: red;
  margin-bottom: 0px;
  padding-top: 15px;
  padding-left: 15px;
  text-align: center;
}

.error {
  color: red;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Multiplication table</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <link rel="stylesheet" href="css/style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.theme.min.css" integrity="sha512-9h7XRlUeUwcHUf9bNiWSTO9ovOWFELxTlViP801e5BbwNJ5ir9ua6L20tEroWZdm+HFBAWBLx2qH4l4QHHlRyg==" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" integrity="sha512-aOG0c6nPNzGk+5zjwyJaoRUgCdOrfSDhmMID2u4+OIslr0GjpLKo7Xm0Ao3xmpM4T8AmIouRkqwj1nrdVsLKEQ==" crossorigin="anonymous" />
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
    
    

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.2/jquery.validate.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
    
    <script src="js/validate.js"></script>
  </head>
  <body>

<div class="containerInput">
  <h2>Multiplication Table</h2>
  <div class="row justify-content-center">
    <div class="col-lg-6 col-md-6-offset-3 col-sm-12 well" >
    <form id="inputForm" class = 'card p-3 bg-light' class="form-horizontal">
      <h6>Please enter range values for your Multiplication Table.</h6>
      <hr>
      <div class="form-group">
        <label class="control-label col-sm-10" for="minCol">Minimum Column Value:</label>
        <div class="col-sm-12">
          <input class="form-control inputfield" id="minCol" name="minCol" value="-50">
        </div>
        <div id="minColSlider" class="sliderMC"></div>
      </div>
      <div class="form-group">
        <label class="control-label col-sm-10" for="maxCol">Maximum Column Value:</label>
        <div class="col-sm-12">
          <input class="form-control inputfield" id="maxCol" name="maxCol" value="-50">
        </div>
        <div id="maxColSlider" class="sliderMC2"></div>
      </div>
      <div class="form-group">
        <label class="control-label col-sm-10" for="minRow">Minimum Row Value:</label>
        <div class="col-sm-12">
          <input class="form-control inputfield" id="minRow" name="minRow" value="-50">
        </div>
        <div id="minRowSlider" class="sliderMR"></div>
      </div>
      <div class="form-group">
        <label class="control-label col-sm-10" for="maxRow">Maximum Row Value:</label>
        <div class="col-sm-12">
          <input class="form-control inputfield" id="maxRow" name="maxRow" value="-50">
        </div>
        <div id="maxRowSlider" class="sliderMR2"></div>
      </div>
      <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
          <button type="submit" class="btn btn-secondary purple-background black">Generate</button>
        </div>
      </div>
    </form>
  </div>
 </div>
</div>

<div id="message">
</div>


 <div id="tableTabs">
  <ul id="tabsList">
  </ul>
</div>


  </body>
</html>

Fiddle demo


Solution

  • Re-initialization of the tabs is failing. You need to destroy them if they exist first.

    if ($('#tableTabs').tabs()) {
        $("#tableTabs").tabs('destroy');
    }
    
    $("#tableTabs").tabs({
      "active": tabs.length - 1
    });
    

    Also note that your table markup is incomplete. It's lacking a closing table row tag:

    <tr><th>&times;</th><th>-50</th></tr><tr><th>-50</th><td>2500</td>
    

    $( document ).ready(function() {
    
      var tabs = [];
      
    //Function to generate a multiplication table based on user's range input.
    function generateTable(minCol, maxCol, minRow, maxRow) {
      let tabsList = document.getElementById("tabsList");
      let tableTabs = document.getElementById("tableTabs");
    
      let tabObject = { 
        name: tabs.length, 
        minCol: minCol,
        maxCol: maxCol,
        minRow: minRow,
        maxRow: maxRow
      };
      tabs.push(tabObject);
    
      let listItem = document.createElement("li");
      let anchor = document.createElement("a");
      anchor.href = `#tab-${tabs.length-1}`;
      anchor.innerText = `tab-${tabs.length-1}`;
      listItem.appendChild(anchor);
      tabsList.appendChild(listItem);
      listItem.classList.add("ui-tabs-tab");
    
      let tableDiv = document.createElement("div");
      tableDiv.id = `tab-${tabs.length-1}`;
      tableTabs.appendChild(tableDiv);
    
      var error = document.getElementById("message");
    
      var table = document.createElement("table");
      var result = "";
      //creating a multTable
      for(var i=minRow; i<=maxRow;i++)
      {
          if(i==minRow)
          {
            result += "<tr>";
            result += "<th>&times;</th>";
          }
    
          for(var j=minCol; j<=maxCol; j++)
          {
              if(i==minRow || j==minCol)
              {
                if(i==minRow)
                  result += "<th>" + j + "</th>";
                else
                  result += "<td>"+ (i-1)*j + "</td>";
              }
              else
                result += "<td>"+ (i-1)*j + "</td>";
          }
            result += "</tr>";
            result += "<tr>";
            result += "<th>" + i + "</th>";
            if(i==maxRow)
            {
              for(var j=minCol; j<=maxCol; j++)
              {
                result += "<td>"+ i*j + "</td>";
              }
            }
        }
      //printing the table
      table.innerHTML=result;
      tableDiv.appendChild(table);
    
      if ($('#tableTabs').tabs()) {
          $("#tableTabs").tabs('destroy');
      }
    
      $("#tableTabs").tabs( { "active" : tabs.length-1});
      return false;
    }
    
    //Function to validate user's input
    $(function() {
      $("#inputForm").submit(function(e) {
        e.preventDefault();
      }).validate({
          submitHandler: function(form) {
          var minCol = parseInt(document.getElementById("minCol").value);
          var maxCol = parseInt(document.getElementById("maxCol").value);
          var minRow = parseInt(document.getElementById("minRow").value);
          var maxRow = parseInt(document.getElementById("maxRow").value);
          generateTable(minCol, maxCol, minRow, maxRow);
          return false;
        }
      });//end validate
    
    });//end function
    
    });
    html {
      background-color: #9FA5FF;
      height: 100%;
    }
    
    body {
      background-color: #E2E3FF;
      margin: 0 auto;
      width: 70%;
    }
    
    h2 {
      padding-top: 20px;
      padding-bottom: 20px;
      text-align: center;
      background-color: #c68de2;
    }
    
    h6 {
      text-align: center;
      margin-bottom: 0px;
    }
    
    .purple-background {
      background-color:#c68de2;
    }
    
    .black {
      color:#000000;
    }
    
    .inputfield{
      height:30px;
    }
    .containerInput {
      padding-left: 0px;
      padding-right: 0px;
    }
    
    .container {
      padding: 20px 0;
      overflow: scroll;
      height: 400px;
    }
    
    #multTable {
      margin: auto;
    }
    
    #multTable td, th {
      width: 50px;
      font-size: 20px;
      border: 1px solid blue;
    }
    
    #multTable td:nth-child(even) {
      background-color: #ffffff;
    }
    
    #multTable th {
      background-color: #9FA5FF;
    }
    
    #message p{
      color: red;
      margin-bottom: 0px;
      padding-top: 15px;
      padding-left: 15px;
      text-align: center;
    }
    
    .error {
      color: red;
    }
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>Multiplication table</title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
        <link rel="stylesheet" href="css/style.css">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.theme.min.css" integrity="sha512-9h7XRlUeUwcHUf9bNiWSTO9ovOWFELxTlViP801e5BbwNJ5ir9ua6L20tEroWZdm+HFBAWBLx2qH4l4QHHlRyg==" crossorigin="anonymous" />
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" integrity="sha512-aOG0c6nPNzGk+5zjwyJaoRUgCdOrfSDhmMID2u4+OIslr0GjpLKo7Xm0Ao3xmpM4T8AmIouRkqwj1nrdVsLKEQ==" crossorigin="anonymous" />
        <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
        
        
    
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.2/jquery.validate.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
        
        <script src="js/validate.js"></script>
      </head>
      <body>
    
    <div class="containerInput">
      <h2>Multiplication Table</h2>
      <div class="row justify-content-center">
        <div class="col-lg-6 col-md-6-offset-3 col-sm-12 well" >
        <form id="inputForm" class = 'card p-3 bg-light' class="form-horizontal">
          <h6>Please enter range values for your Multiplication Table.</h6>
          <hr>
          <div class="form-group">
            <label class="control-label col-sm-10" for="minCol">Minimum Column Value:</label>
            <div class="col-sm-12">
              <input class="form-control inputfield" id="minCol" name="minCol" value="-50">
            </div>
            <div id="minColSlider" class="sliderMC"></div>
          </div>
          <div class="form-group">
            <label class="control-label col-sm-10" for="maxCol">Maximum Column Value:</label>
            <div class="col-sm-12">
              <input class="form-control inputfield" id="maxCol" name="maxCol" value="-50">
            </div>
            <div id="maxColSlider" class="sliderMC2"></div>
          </div>
          <div class="form-group">
            <label class="control-label col-sm-10" for="minRow">Minimum Row Value:</label>
            <div class="col-sm-12">
              <input class="form-control inputfield" id="minRow" name="minRow" value="-50">
            </div>
            <div id="minRowSlider" class="sliderMR"></div>
          </div>
          <div class="form-group">
            <label class="control-label col-sm-10" for="maxRow">Maximum Row Value:</label>
            <div class="col-sm-12">
              <input class="form-control inputfield" id="maxRow" name="maxRow" value="-50">
            </div>
            <div id="maxRowSlider" class="sliderMR2"></div>
          </div>
          <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
              <button type="submit" class="btn btn-secondary purple-background black">Generate</button>
            </div>
          </div>
        </form>
      </div>
     </div>
    </div>
    
    <div id="message">
    </div>
    
    
     <div id="tableTabs">
      <ul id="tabsList">
      </ul>
    </div>
    
    
      </body>
    </html>