Reputation: 286
The table is like this:
<table id="sample_table">
<tr>
<td>1</td>
<td><input type="text" size="5" id="in2" name="txt2" value="0"/></td>
<td><input type="text" size="5" id="in3" name="txt3" value="0"/></td>
<td><input type="text" size="5" id="in4" name="txt4" value="0"/></td>
</tr>
the js code is like this:
function export(filename) {
var csv = [];
var rows = document.getElementById('tbl_posts').querySelectorAll("table tr");
for (var i = 0; i < rows.length; i++) {
var row = [], cols = rows[i].querySelectorAll("td, th");
for (var j = 0; j < cols.length; j++){
row.push(cols[j].innerText);
}
csv.push(row.join(","));
}
// Download CSV file not posted here
downloadCSV(csv.join("\n"), filename);
}
and the export button:
<button type="button" onclick="export('myFile')">Export</button>
since it reads td not input fields it adds empty '' strings into csv list. How can I access inputs and push them into row list?
Upvotes: 3
Views: 1106
Reputation: 2408
Just a variation on @Aaron's answer, giulp's way :)
... using .map is definitely the way I'd choose, more concise, less error prone, see @Ifaruki's answer for yet another path in this direction
function fetchData(filename) {
let cells = document.querySelectorAll("table#sample_table tr td");
// using map over a NodeList -> see below
var csv = Array.prototype.map.call(cells, function(cell){
// if the first is undefined (falsey in js)
// then return the second, a widely used pattern
return cell.firstChild.value || cell.innerText;
}).join(",");
console.log(csv);
}
<table id="sample_table">
<tr>
<td>1</td>
<td><input type="text" size="5" id="in2" name="txt2" value="0" /></td>
<td><input type="text" size="5" id="in3" name="txt3" value="0" /></td>
<td><input type="text" size="5" id="in4" name="txt4" value="0" /></td>
</tr>
</table>
<button type="button" onclick="fetchData('myFile')">Export</button>
Upvotes: 0
Reputation: 14904
You could also go with Array.from
and map it
function fetchData() {
let data = Array.from(document.querySelectorAll("#sample_table td"))
.map(el => el.firstChild.value || el.innerText)
.join(",");
console.log(data);
}
<table id="sample_table">
<tr>
<td>1</td>
<td><input type="text" size="5" id="in2" name="txt2" value="0"/></td>
<td><input type="text" size="5" id="in3" name="txt3" value="0"/></td>
<td><input type="text" size="5" id="in4" name="txt4" value="0"/></td>
<button onclick="fetchData()">Fetch</button>
</tr>
Upvotes: 2
Reputation: 1178
I saw your comments. If we seek a solution by minimum editing to your code and also I don't know the rest of the document structure, then this will work for multiple rows.
The basic idea is when you already have a table row, then all you need is inputs inside them. So we seek inputs and then go on them one by one.
function exportF(filename) {
var csv = [];
var rows = document.getElementById('sample_table').querySelectorAll("table tr");
for (var i = 0; i < rows.length; i++) {
var row = [], cols = rows[i].querySelectorAll("input");
for (var j = 0; j < cols.length; j++){
//console.log(cols[j])
row.push(cols[j].value);
}
csv.push(row.join(","));
}
// Download CSV file not posted here
console.log(csv.join("\n"));
}
Link to fiddle: https://jsfiddle.net/tewo2drn/1/
Upvotes: 2
Reputation: 1737
If you can ensure only inputs occur as child nodes inside a td you could use the following approach. When iterating over a td check if there are any child nodes (only happens in your example if an input is inside a td).
If there's a child (input) use .value
on the child to get the value. Otherwise use .innerText
. If there is something unclear, feel free to comment :)
function fetchData(filename) {
var csv = [];
var rows = document.getElementById('sample_table').querySelectorAll("table tr");
for (var i = 0; i < rows.length; i++) {
var row = [],
cols = rows[i].querySelectorAll("td, th");
for (var j = 0; j < cols.length; j++) {
if (cols[j].children.length > 0) { //assuming your structure is always the same and the table only contains inputs as child elements inside a td
row.push(cols[j].firstChild.value);
} else {
row.push(cols[j].innerText);
}
}
csv.push(row.join(","));
}
console.log(csv);
}
<table id="sample_table">
<tr>
<td>1</td>
<td><input type="text" size="5" id="in2" name="txt2" value="0" /></td>
<td><input type="text" size="5" id="in3" name="txt3" value="0" /></td>
<td><input type="text" size="5" id="in4" name="txt4" value="0" /></td>
</tr>
</table>
<button type="button" onclick="fetchData('myFile')">Export</button>
Upvotes: 3
Reputation: 751
What I think is you want to push each row's input value into a CSB file. Then you have to change you cols code like this
cols = document.querySelectorAll("td input, the input");
for (var j = 0; j < cols.length; j++){
row.push(cols[j].value);
}
I think this would work
Upvotes: 2