【发布时间】:2020-05-21 23:32:18
【问题描述】:
我目前正在为客户的问卷调查应用程序“导出到 csv”,其中所有用户输入数据都被捕获并写入 .csv 文件。
在由 getElementsByTagName() 捕获的 HTML 集合中同时存在 <input> 和 <select> 元素。下面是我的 HTML 外观的 sn-p:
<tr>
<td><input type="text" id="person1" name="person1"></td>
<td>
<select name="person1_lang1_primary" id="person1_lang1_select">
<option value=""></option>
<option value="english">English</option>
<option value="Spanish">Spanish</option>
<option value="other1">Other1 - specify below</option>
<option value="other2">Other2 - specify below</option>
<option value="other3">Other3 - specify below</option>
<option value="other4">Other4 - specify below</option>
</select>
</td>
<tr>
解决这一切的功能是:
class TableCSVExporter {
constructor (table, includeHeaders = true) {
this.table = table;
this.rows = Array.from(table.querySelectorAll("tr"));
if(!includeHeaders && this.rows[0].querySelectorAll("th").length) {
this.rows.shift();
}
}
convertToCSV() {
const lines = [];
const numCols = this._findLongestRowLength();
for(const row of this.rows) {
let line = "";
for(let i = 0; i < numCols; i++) {
if (row.children[i] !== undefined) {
line += TableCSVExporter.parseCell(row.children[i]);
}
line += (i !== (numCols - 1)) ? "," : "";
}
lines.push(line);
// console.log(row);
}
return lines.join("\n");
}
_findLongestRowLength() {
return this.rows.reduce((l, row) => row.childElementCount > l ? row.childElementCount : l, 0);
}
static parseCell (tableCell) {
let input_elements = tableCell.getElementsByTagName("input");
let select_elements = tableCell.getElementsByTagName("select");
let inputArray = Array.from(input_elements);
let selectArray = Array.from(select_elements);
let elementsArray = [...inputArray, ...selectArray];
let parsedValue = [...elementsArray];
// Replace all double quotes with two double quotes
parsedValue = parsedValue.replace(/"/g, `""`);
// If value contains comma, new-line or double-quote, enclose in double quotes
parsedValue = /[", \n]/.test(parsedValue) ? `"${parsedValue}"` : parsedValue;
inputArray.forEach(element => console.log(element.value));
selectArray.forEach(element => console.log(element.value));
elementsArray.forEach(element => console.log(element.value));
return parsedValue;
}
}
HTML 文件中还有一个<script>,其中包含以下内容:
<script>
const primaryInputByPerson = document.getElementById("primaryInputByPerson");
const btnExportCSV = document.getElementById("btnExportToCSV");
btnExportCSV.addEventListener("click", () => {
const exporter = new TableCSVExporter(primaryInputByPerson);
const csvOutput = exporter.convertToCSV();
const csvBlob = new Blob([csvOutput], {type: "text/csv" });
const blobURL = URL.createObjectURL(csvBlob);
const anchorElement = document.createElement("a");
anchorElement.href = blobURL;
// sets the name of the file the user will download
anchorElement.download = "LEAT-data.csv";
anchorElement.click();
// reduces the amount of memory used by the browser
setTimeout(() => {
URL.revokeObjectURL(blobURL);
}, 500);
})
// console.log(new TableCSVExporter(primaryInputByPerson).convertToCSV());
</script>
我已经到了可以控制台记录来自inputArray 和selectArray 的每个元素的用户输入值的地步,尽管我似乎不知道如何让parsedValue 保存价值观。我将tableCell 转换为一个数组,因为我读到NodeLists 和HTMLcollections 不提供与常规数组相同的功能。我实际上是在尝试使用 .value 来获取值,就像在大多数 DOM 场景中一样。
下载的 .csv 文件将显示 undefined、null 或 [object HTMLInputElement]/[object HTMLSelectElement],具体取决于我的 console.log()。
这是我在网站上的第一个问题。我想我可能会打破一些(或很多)惯例,欢迎任何关于未来提出更好问题的反馈!
注意:我将所有功劳归功于 Domenic Corso 和他的视频 https://www.youtube.com/watch?v=cpHCv3gbPuk&t=713s,因为他们几乎提出了上述所有代码!
【问题讨论】:
-
好吧..输入元素的id是
person1所以..使用它。 -
感谢@GottZ 的反馈!我尝试在 tableCell 上使用 .getElementById(),尽管它会抛出一个错误,说“getElementById 不是一个函数”......最重要的是,我没有在我的问题中提到我的应用程序有很多 和 元素,所以我需要在一次调用中获取所有这些元素。
-
其次,您所说的
.getElementById()电话在哪里。我在您提供的代码中看不到它。不要假设人们会窃取您在此处发布的所有内容。 tbh 我是那种甚至可以用更简洁的代码重新实现你的想法的人。 ps:如果您遇到需要带有某种反作弊系统的表单的客户,请以此为灵感:gottz.de/visibility.htm -
哦,我没有省略它,因为我以为有人会偷。就像我在底部发帖一样,我不能将大部分代码归功于我,因为我正在关注另一个开发人员的教程。我意识到我把它换成我的编辑器中的代码来尝试它,发现它不起作用。我没有在这里反映。再次感谢您的反馈!
标签: javascript html csv dom nodelist