Home > Back-end >  Export html table that contain a drop down list with Javascript
Export html table that contain a drop down list with Javascript

Time:10-18

I have a table that allow user to add more column, inside the added column's cell there is a drop down list option. I tried to implement an export csv function but it seem like only work on table that is without drop down list. I do not know how can I get the selected item in the drop down list. enter image description here

The output of my export:

enter image description here

As you can see the exported file doesn't format the table properly and its total mess. All my drop down list options are show on the A column, but what I really need is only show the selected value on their correct column which are Group1.

Question

  1. How can I export csv files with correct format with the selected drop down list value?
  2. If user choose Null as their option, how can I make the exported csv column empty? For example: if user choose Null, the exported csv file should not contain any value and only store an empty cell.

Full Code:

<!DOCTYPE html>
<html>
<head>
<style>
table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td, th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
}

tr:nth-child(even) {
  background-color: #dddddd;
}
</style>
</head>
<body>

<h2>HTML Table</h2>

<h2>HTML Table</h2>

<table id="member_table">
  <tr>
    <th>Company</th>
    <th>Contact</th>
    <th>Country</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Centro comercial Moctezuma</td>
    <td>Francisco Chang</td>
    <td>Mexico</td>
  </tr>
  <tr>
    <td>Ernst Handel</td>
    <td>Roland Mendel</td>
    <td>Austria</td>
  </tr>
  <tr>
    <td>Island Trading</td>
    <td>Helen Bennett</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>Laughing Bacchus Winecellars</td>
    <td>Yoshi Tannamuri</td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Giovanni Rovelli</td>
    <td>Italy</td>
  </tr>
</table>

 <h1>Existing Group</h1>
      <p>IT, Cleaning, Accountant</p>
      <h1>Add New Group</h1>
      <p id="myP"></p>
      <input type="tel" id="group" name="group" placeholder="enter group name">
      <br><br>
      <button type="button" class="btn btn-primary btn-sm">Submit</button>
   

<button onclick="javascript:appendColumn()">Add column</button>
  <button onclick="export2csv()">csv</button>

<script>
function createSelectEl(values){
    var select = document.createElement("select");
    select.name = "group1";
    select.id = "groupId"
    // 1st option
    var option = document.createElement("option");
    option.text = 'Null';
    select.appendChild(option);
    for (const val of values)
    {
        var option = document.createElement("option");
        option.value = val;
        option.text = val;
        select.appendChild(option);
    }
    return select;
}

let groupNum = 1;
const tableEl = document.getElementById('member_table');

// append column to the HTML table
function appendColumn() {

  // open loop for each row and append cell
  for (let i = 0; i < tableEl.rows.length; i  ) {
    const values = ["IT", "Cleaning", "Accountant"];
    const myP  = document.querySelector('p#myP');
    var categories = myP.innerText.split(',');
    for(let j =0; j < categories.length; j  ){
    values.push(categories[j]);
    }
    createCell(tableEl.rows[i].insertCell(tableEl.rows[i].cells.length), createSelectEl(values), 'col');
    // createCell(tableEl.rows[i].insertCell(tableEl.rows[i].cells.length), i, 'col');
  }

  tableEl.rows[0].querySelector('td:last-child').textContent = 'Group'   groupNum;
  groupNum  ;
}

// create DIV element and append to the table cell
function createCell(cell, text, style) {
  var div = document.createElement('div'); // create DIV element
    //txt = document.createTextNode(text); // create text node
  // div.appendChild(txt); // append text node to the DIV
  div.appendChild(text);
  div.setAttribute('class', style); // set DIV class attribute
  div.setAttribute('className', style); // set DIV class attribute for IE (?!)
  cell.appendChild(div); // append DIV to the table cell
}
</script>

<script>
function export2csv() {
  let data = "";
  const tableData = [];
  const rows = document.querySelectorAll("table tr");
  for (const row of rows) {
    const rowData = [];
    for (const [index, column] of row.querySelectorAll("th, td").entries()) {
      // To retain the commas in the "Description" column, we can enclose those fields in quotation marks.
      if ((index   1) % 3 === 0) {
        rowData.push('"'   column.innerText   '"');
      } else {
        rowData.push(column.innerText);
      }
    }
    tableData.push(rowData.join(","));
  }
  data  = tableData.join("\n");
  const a = document.createElement("a");
  a.href = URL.createObjectURL(new Blob([data], { type: "text/csv" }));
  a.setAttribute("download", "data.csv");
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}
</script>
<script>
const submit = document.querySelector('button');
const input  = document.querySelector('input');
const select = document.querySelector('select');
const myP    = document.querySelector('p#myP');

submit.addEventListener('click', function(e)
{
  const values = input.value.split(',');
  
  if (myP.innerText == '')
  {
    myP.innerText = values;
  }
  else
  {
    myP.innerText  = ', '   values;
  }
  
});
</script>
</body>
</html>



CodePudding user response:

You just need to update your export2csv function to account for the select element. I check if the td contains a select element first and if it does I process if differently:

function export2csv() {
  let data = "";
  const tableData = [];
  const rows = document.querySelectorAll("table tr");
  for (const row of rows) {
    const rowData = [];
    for (const [index, column] of row.querySelectorAll("th, td").entries()) {
      const select = column.querySelector('select');
      const text = column.innerText;
      if(select){
        if(select.value && select.value.toLowerCase() !== 'null') {
          rowData.push(select.value);
        } else {
          rowData.push('');
        }
      } else if (text.includes(',')) {
        // If the data contains commas wrap it in quotations.
        rowData.push(`"${text}"`);
      } else {
        rowData.push(text);
      }
    }
    tableData.push(rowData.join(","));
  }
  data  = tableData.join("\n");
  const a = document.createElement("a");
  a.href = URL.createObjectURL(new Blob([data], { type: "text/csv" }));
  a.setAttribute("download", "data.csv");
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}

You might want to consider removing Null as the value of the first option in your select elements. It would be better if the first option was empty:

// 1st option
var option = document.createElement("option");
option.text = '';

This would then simplify what you have to check for in your export2csv function:

if(select.value) {
    rowData.push(select.value);
} else {
    rowData.push('');
}
  • Related