Home > Software engineering >  How to extract data from an html table where cells have different types?
How to extract data from an html table where cells have different types?

Time:09-10

I have two problems to solve. I am trying to create an editable table which the user enters data into. Two of the columns are number input and one column is a select value. The fourth column is action buttons for new,edit,delete. I have searched everywhere for some kind of tutorial on how to do this but found nothing useful. The table row is created in javascript when the user clicks on Add New. They then click on a green add icon to accept the data.
In my javascript I have written a little function called displayTableData() which I call when the user clicks the 'add' button. This was just to verify that I could extract the data and display it in an alert. But nothing happens. Furthermore, using cell.innerHTML doesn't work on a 'select' value.

The second problem is that after the user clicks on 'add' and the data is accepted, if they then click on the 'edit' button the 'select' drop down is lost.

You can try this out in my code snippet. I notice when I run this I am getting an uncaught error but don't understand why. I am new to javascript. I would have expected millions of people to have done something like this but I couldn't find an entire example that worked.

$(document).ready(function(){
  $('[data-toggle="tooltip"]').tooltip();
// Append table with add row form on add new button click
$(".add-new-your-super-contribution").click(function(){
  $(this).attr("disabled", "disabled");
  var index = $("table tbody tr:last-child").index();
      var row = '<tr>'  
          '<td label="Age" ><input type="text"  name="age" id="age"></td>'  

          '<td label="Contribution" ><input type="text"  name="contribution" id="contribution"></td>'  
                  
          '<td label="Taxation">'  
            '<select id="your-super-contribution">'  
              '<option id="your-before-tax-super-contribution">Before</option>'  
             '<option id="your-after-tax-super-contribution">After</option>'  
            '</select>'  
          '</td>'  
   
          '<td label="Actions" ><a  title="Add" data-toggle="tooltip"><i >&#xE03B;</i></a>'  
    '<a  title="Edit" data-toggle="tooltip"><i >&#xE254;</i></a>'  
     '<a  title="Delete" data-toggle="tooltip"><i >&#xE872;</i></a></td>'  
      '</tr>';
    $("table").append(row);     
  $("table tbody tr").eq(index   1).find(".add-your-super-contribution, .edit").toggle();
      $('[data-toggle="tooltip"]').tooltip();
  });

    // Add row on add button click
    $(document).on("click", ".add-your-super-contribution", function(){
        var empty = false;
        var input = $(this).parents("tr").find('input[type="text"]');
        input.each(function(){
            if(!$(this).val()){
                $(this).addClass("error");
                empty = true;
            } else{
          $(this).removeClass("error");
      }
        });
        $(this).parents("tr").find(".error").first().focus();
        if(!empty){
            input.each(function(){
                $(this).parent("td").html($(this).val());
            }); 
            $(this).parents("tr").find(".add-your-super-contribution, .edit").toggle();
            $(".add-new-your-super-contribution").removeAttr("disabled");
      displayTableData();
        }       
    });


    // Edit row on edit button click
    $(document).on("click", ".edit", function(){        
        $(this).parents("tr").find("td:not(:last-child)").each(function(){
            $(this).html('<input type="text"  value="'   $(this).text()   '">');
        });     
        $(this).parents("tr").find(".add-your-super-contribution, .edit").toggle();
        $(".add-new-your-super-contribution").attr("disabled", "disabled");
    });


    // Delete row on delete button click
    $(document).on("click", ".delete", function(){
        $(this).tooltip('hide');

      //  $(this).off();
      $(this).parents("tr").remove();
      $(".add-new-your-super-contribution").removeAttr("disabled");
  });
});

function deleteAllYourSuperContribution() {
  $("#your-super-contributions-table > tbody").empty();
}

function displayTableData() {
  var tableBody = document.getElementById("your-super-contribution-table").getElementsByTagName('tbody')[0];

  var values = [];

  for (var r = 0, n = tableBody.rows.length; r < n; r  ) {
    for (var c = 0, m = tableBody.rows[r].cells.length; c < m; c  ) {
      cell = tableBody.rows[r].cells[c];
      values[r][c] = cell.innerHTML;
      alert("values "   r   " "   c   " "   values[r][c]);
    }
  }
}
/***************************************************************************/
/*                    TABLES                                               */
/**************************************************************************/
table th {
  color: #22769D !important;
  font-weight: bold;
}

table {
  color: #444;
  background-color: #FFF;
  font-size: 70%;
}

.center {
  text-align: center;
}
.align-right {
  text-align: right;
}

.table-title-border {
  width: 100%;
  height: 10px;
  border-top: 1px solid #22769D !important;
  margin-top: 10px;
}

table.table input {
  font-size: 95%;
}

.form-button {
  border: 1px solid #FE6D73;
  background-color: #FEF9EF !important;
  color: #22769D;
  font-size: 80%;
  border-radius: 5px 5px 5px 5px;
}



.table-wrapper {
  background-color: #FEF9EF !important;
  width: 70%;
  margin: 0 auto;
  padding: 20px;    
}
.table-title {
  padding-bottom: 10px;
  margin: 0 0 10px;
}
.table-title h2 {
  margin: 6px 0 0;
  font-size: 22px;
}
.table-title .add-new .delete-all {
  float: right;
  height: 30px;
  font-weight: bold;
  font-size: 12px;
  text-shadow: none;
  min-width: 100px;
  border-radius: 50px;
  line-height: 13px;
}

table.table {
  table-layout: fixed;
}
table.table tr th, table.table tr td {
  border-color: #e9e9e9;
}
table.table tr td {
  padding: 3px;
}

table.table th i {
  font-size: 13px;
  margin: 0 5px;
  cursor: pointer;
}
table.table th:last-child {
  width: 100px;
}
table.table td a {
  cursor: pointer;
  display: inline-block;
  margin: 0 5px;
  min-width: 24px;
}    
table.table td a.add-your-super-contribution {
  color: #27C46B;
}
table.table td a.edit {
  color: #FFC107;
}
table.table td a.delete {
  color: #E34724;
}
table.table td i {
  font-size: 19px;
}
table.table td a.add-your-super-contribution i {
  font-size: 24px;
  margin-right: -1px;
  position: relative;
  top: 3px;
}    
table.table .form-control {
  height: 32px;
  line-height: 32px;
  box-shadow: none;
  border-radius: 2px;
}
table.table .form-control.error {
  border-color: #f50000;
}
table.table td .add-your-super-contribution {
  display: none;
}


/****************************** NAVIGATION MEDIQ QUERY  690 px ******************/
@media (max-width: 43.125em) {

  .table-wrapper {
    width: 96%;
  }

  .table-dropdown .nav-link {
    height: 20px;
  }

  table.table tr td {
    padding: 1px;
  }


}

/***************************************************************************************/
/* Phones from up to 319 px                                                            */
/***************************************************************************************/
@media only screen and (max-width: 19.938em) {

  .table-dropdown .nav-link {
    height: 20px;
  }

}

/****************************************************************************************/
/* Phones from 320px up to 479px                                                        */
/*****************************************************************************************/
@media only screen and (min-width: 20em) {


}

/****************************************************************************************/
/* Phones from 480px up to 599px                                                        */
/*****************************************************************************************/
@media only screen and (min-width: 30em) {
  .table-dropdown .nav-link {
    height: 25px;
  }
}


/****************************************************************************************/
/* landscape tablets from 768px up to 991px                                              */
/*****************************************************************************************/
@media only screen and (min-width: 48em) {

  .table-dropdown .nav-link {
    height: 30px;
  }
}

/****************************************************************************************/
/* Large devices from 992px to 1199px                                                    */
/*****************************************************************************************/
@media only screen and (min-width: 62em) {
 

}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto|Varela Round|Open Sans">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material Icons">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
  <link rel="stylesheet" href="style.css"/>
</head>
<body>

  <div >

    <div >
        <div >
            <div >
                <div ><h2>Extra Lump Sum Contributions</h2></div>
                <div >
                    <button type="button" ><i ></i> Add New</button>
                    <button type="button"  onClick="deleteAllYourSuperContribution()"><i ></i> Delete All</button>
                </div>
            </div>  <!---- end row -->
        </div> <!-- end table-title -->

  <table  id="your-super-contribution-table">

    <colgroup>
      <col span="1" style="width: 17%;">
      <col span="1" style="width: 28%;">
      <col span="1" style="width: 28%;">
      <col span="1" style="width: 27%;">
    </colegroup>

    <thead >
        <tr>
            <th >Age</th>
            <th >Contribution</th>
            <th >Taxation</th>
            <th >Actions</th>
        </tr>
    </thead>
    <tbody>
    
    </tbody>
  </table>
  </div>
  </div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
  <script type="text/javascript" src="script.js"></script>
  
  
</body>
</html>

CodePudding user response:

A lot of issues

The error was a comma in the selector so that was simple

I had to rewrite several parts of the code. Please study what I did.

One important thing was to move the ID of the table to the tbody and cache it

Another thing was to not have duplicate IDs

If you do NOT disable the add after first click you will need to rewrite the converting the text fields and select to values

Alternatively use contenteditable

$(document).ready(function() {
  const $table = $("#your-super-contribution-table");
  
const deleteAllYourSuperContribution = () => { $table.empty(); };
const displayTableData = () => {
  const values = $table.find("tr").map(function() { 
    return $("td[data-label]",this).map(function() { 
      return { [this.dataset.label] : this.dataset.label === "Taxation" ? this.querySelector("select").value : this.textContent.trim() }
    }).get()
  }).get()
  console.log(values)
};  
  
  const row = `<tr>
  <td data-label="Age" ><input type="text"  name="age" ></td> '
  <td data-label="Contribution" ><input type="text"  name="contribution"></td>
  <td data-label="Taxation">
    <select >
      <option id="your-before-tax-super-contribution">Before</option>
      <option id="your-after-tax-super-contribution">After</option>
    </select>
  </td>
  <td label="Actions" ><a  title="Add" data-toggle="tooltip"><i >&#xE03B;</i></a>
    <a  title="Edit" data-toggle="tooltip"><i >&#xE254;</i></a><a  title="Delete" data-toggle="tooltip"><i >&#xE872;</i></a></td>
</tr>`;

  $('[data-toggle="tooltip"]').tooltip();
  // Append table with add row form on add new button click
  $(".add-new-your-super-contribution").click(function() {
    $(this).attr("disabled", "disabled");
    var index = $("table tbody tr:last-child").index();
    $table.append(row);
    $table.find("tr").eq(index   1).find(".add-your-super-contribution, .edit").toggle();
    $('[data-toggle="tooltip"]').tooltip();
  });

  // Add row on add button click
  $(document).on("click", ".add-your-super-contribution", function() {
    var empty = false;
    var input = $(this).parents("tr").find('input[type="text"]');
    input.each(function() {
      if (!$(this).val()) {
        $(this).addClass("error");
        empty = true;
      } else {
        $(this).removeClass("error");
      }
    });
    $(this).parents("tr").find(".error").first().focus();
    if (!empty) {
      input.each(function() {
        $(this).parent("td").html($(this).val());
      });
      $(this).parents("tr").find(".add-your-super-contribution, .edit").toggle();
      $(".add-new-your-super-contribution").removeAttr("disabled");
      displayTableData();
    }
  });


  // Edit row on edit button click
  $(document).on("click", ".edit", function() {
    $(this).parents("tr").find("td:not(:last-child)").each(function() {
      $(this).html('<input type="text"  value="'   $(this).text()   '">');
    });
    $(this).parents("tr").find(".add-your-super-contribution .edit").toggle();
    $(".add-new-your-super-contribution").attr("disabled", "disabled");
  });


  // Delete row on delete button click
  $(document).on("click", ".delete", function() {
    $(this).tooltip('hide');

    //  $(this).off();
    $(this).parents("tr").remove();
    $(".add-new-your-super-contribution").removeAttr("disabled");
  });
});
/***************************************************************************/


/*                    TABLES                                               */


/**************************************************************************/

table th {
  color: #22769D !important;
  font-weight: bold;
}

table {
  color: #444;
  background-color: #FFF;
  font-size: 70%;
}

.center {
  text-align: center;
}

.align-right {
  text-align: right;
}

.table-title-border {
  width: 100%;
  height: 10px;
  border-top: 1px solid #22769D !important;
  margin-top: 10px;
}

table.table input {
  font-size: 95%;
}

.form-button {
  border: 1px solid #FE6D73;
  background-color: #FEF9EF !important;
  color: #22769D;
  font-size: 80%;
  border-radius: 5px 5px 5px 5px;
}

.table-wrapper {
  background-color: #FEF9EF !important;
  width: 70%;
  margin: 0 auto;
  padding: 20px;
}

.table-title {
  padding-bottom: 10px;
  margin: 0 0 10px;
}

.table-title h2 {
  margin: 6px 0 0;
  font-size: 22px;
}

.table-title .add-new .delete-all {
  float: right;
  height: 30px;
  font-weight: bold;
  font-size: 12px;
  text-shadow: none;
  min-width: 100px;
  border-radius: 50px;
  line-height: 13px;
}

table.table {
  table-layout: fixed;
}

table.table tr th,
table.table tr td {
  border-color: #e9e9e9;
}

table.table tr td {
  padding: 3px;
}

table.table th i {
  font-size: 13px;
  margin: 0 5px;
  cursor: pointer;
}

table.table th:last-child {
  width: 100px;
}

table.table td a {
  cursor: pointer;
  display: inline-block;
  margin: 0 5px;
  min-width: 24px;
}

table.table td a.add-your-super-contribution {
  color: #27C46B;
}

table.table td a.edit {
  color: #FFC107;
}

table.table td a.delete {
  color: #E34724;
}

table.table td i {
  font-size: 19px;
}

table.table td a.add-your-super-contribution i {
  font-size: 24px;
  margin-right: -1px;
  position: relative;
  top: 3px;
}

table.table .form-control {
  height: 32px;
  line-height: 32px;
  box-shadow: none;
  border-radius: 2px;
}

table.table .form-control.error {
  border-color: #f50000;
}

table.table td .add-your-super-contribution {
  display: none;
}


/****************************** NAVIGATION MEDIQ QUERY  690 px ******************/

@media (max-width: 43.125em) {
  .table-wrapper {
    width: 96%;
  }
  .table-dropdown .nav-link {
    height: 20px;
  }
  table.table tr td {
    padding: 1px;
  }
}


/***************************************************************************************/


/* Phones from up to 319 px                                                            */


/***************************************************************************************/

@media only screen and (max-width: 19.938em) {
  .table-dropdown .nav-link {
    height: 20px;
  }
}


/****************************************************************************************/


/* Phones from 320px up to 479px                                                        */


/*****************************************************************************************/

@media only screen and (min-width: 20em) {}


/****************************************************************************************/


/* Phones from 480px up to 599px                                                        */


/*****************************************************************************************/

@media only screen and (min-width: 30em) {
  .table-dropdown .nav-link {
    height: 25px;
  }
}


/****************************************************************************************/


/* landscape tablets from 768px up to 991px                                              */


/*****************************************************************************************/

@media only screen and (min-width: 48em) {
  .table-dropdown .nav-link {
    height: 30px;
  }
}


/****************************************************************************************/


/* Large devices from 992px to 1199px                                                    */


/*****************************************************************************************/

@media only screen and (min-width: 62em) {}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto|Varela Round|Open Sans">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material Icons">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
  <link rel="stylesheet" href="style.css" />
</head>

<body>

  <div >

    <div >
      <div >
        <div >
          <div >
            <h2>Extra Lump Sum Contributions</h2>
          </div>
          <div >
            <button type="button" ><i ></i> Add New</button>
            <button type="button"  onClick="deleteAllYourSuperContribution()"><i ></i> Delete All</button>
          </div>
        </div>
        <!---- end row -->
      </div>
      <!-- end table-title -->

      <table >

        <colgroup>
          <col span="1" style="width: 17%;">
          <col span="1" style="width: 28%;">
          <col span="1" style="width: 28%;">
          <col span="1" style="width: 27%;">
          </colgroup>

          <thead >
            <tr>
              <th >Age</th>
              <th >Contribution</th>
              <th >Taxation</th>
              <th >Actions</th>
            </tr>
          </thead>
          <tbody id="your-super-contribution-table">

          </tbody>
      </table>
    </div>
  </div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
  <script type="text/javascript" src="script.js"></script>


</body>

</html>

CodePudding user response:

i made some changes in your function, now the error is gone however i am not sure about functionality. see if it's working as per expectation.

function displayTableData() {
  var tableBody = document.getElementById("your-super-contribution-table").getElementsByTagName('tbody')[0];

  var values = [];

  for (var r = 0, n = tableBody.rows.length; r < n; r  ) {
    for (var c = 0, m = tableBody.rows[r].cells.length; c < m; c  ) {
      cell = tableBody.rows[r].cells[c];
      values[r] = values[r]||[]
      values[r][c] = cell.innerHTML;
      alert("values "   r   " "   c   " "   values[r][c]);
    }
  }
}
  • Related