2

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>



1 Answer 1

1

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('');
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.