问题
概括
为离线使用而设计的 HTML 表单无法正确导出/导入数据。有没有对菜鸟友好的解决方案?
细节
此表单的设计目的是让用户可以打开 HTML 表单、填写表单并将数据导出为 pip 分隔的 .txt 文件。
它可以导入/导出名称、性别和城市等各种字段。但是,它 不能导入/导出小吃偏好和晚餐偏好。在我们的数据集中,这意味着成员“贪婪的小猫”将被提供汤而不是鸟,以及奶酪(不需要的)。
初始表单为空:
您可以填写表格并单击“将数据保存到文件”按钮:
但是,当您使用“选择文件”按钮导入相同的数据时,条目会混淆:
代码
Encodedna代码已被重新调整以适应问题。它由三个部分组成:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Offline Form 0.1</title>
</head>
<body>
<div>
<input type="file" name="inputfile" id="inputfile">
</div>
<fieldset>
<legend>Elite Club Member</legend>
<!-- Static -->
<b>Name:</b>
<div id="Name"></div>
<b>DoB:</b>
<input type="date" id="DoB"/><br>
<!-- dropdown, prefilled -->
<b>Gender:</b>
<select id="Gender" name="Gender">
<option value="Male">Male</option>
<option value="Female">Female</option>
<option value="Other">Other</option>
</select>
<br>
<!-- prefilled, but editable-->
<b>City:</b>
<input type="text" id="City"/><br>
</fieldset>
<!-- PROBLEM -->
<fieldset>
<legend>Snack Preferences</legend>
<input type="checkbox" id="cheeseLover" name="cheeseLover">Member loves cheese.
<br>
<input type="checkbox" id="milkLover" name="milkLover">Member loves milk.
<br>
</fieldset>
<!-- PROBLEM -->
<fieldset>
<legend>Dinner Preference</legend>
<ol>
<li>
<legend>Choose among the various dinner options</legend>
<p><label> <input type="radio" id="dinnerPizza" name="dinnerOptions" value="dinnerPizza">Pizza</label></p>
<p><label> <input type="radio" id="dinnerSalad" name="dinnerOptions" value="dinnerSalad">Salad</label></p>
<p><label> <input type="radio" id="dinnerBird" name="dinnerOptions" value="dinnerBird">Bird</label></p>
<p><label> <input type="radio" id="dinnerSoup" name="dinnerOptions" value="dinnerSoup">Soup</label></p>
</li>
</ol>
</fieldset>
<!-- Save button -->
<div>
<input type="button" id="bt" value="Save data to file" onclick="saveFile()" />
</div>
<script type="text/javascript">
document.getElementById('inputfile').addEventListener('change', function() {
var fr=new FileReader();
fr.onload=function(){
var output_data=fr.result;
var output_data_lines = output_data.split('\n');
for(var i = 0; i < output_data_lines.length; i++){
<!-- Patient Info -->
if (output_data_lines[i].split('|')[0] == 'Name') {
document.getElementById('Name').textContent = output_data_lines[i].split('|')[1];
}
else if (output_data_lines[i].split('|')[0] == 'DoB') {
document.getElementById('DoB').value = output_data_lines[i].split('|')[1];
}
else if (output_data_lines[i].split('|')[0] == 'Gender') {
document.getElementById('Gender').value = output_data_lines[i].split('|')[1];
}
<!-- Extra Info -->
else if (output_data_lines[i].split('|')[0] == 'City') {
document.getElementById('City').value = output_data_lines[i].split('|')[1];
}
<!-- PROBLEM -->
<!-- Snack Preference -->
else if (output_data_lines[i].split('|')[0] == 'cheeseLover') {
document.getElementById('cheeseLover').checked = output_data_lines[i].split('|')[1];
}
else if (output_data_lines[i].split('|')[0] == 'milkLover') {
document.getElementById('milkLover').checked = output_data_lines[i].split('|')[1];
}
<!-- PROBLEM -->
<!-- Dinner Preferences -->
else if (output_data_lines[i].split('|')[0] == 'dinnerPizza') {
document.getElementById('dinnerPizza').checked = output_data_lines[i].split('|')[1];
}
else if (output_data_lines[i].split('|')[0] == 'dinnerSalad') {
document.getElementById('dinnerSalad').checked = output_data_lines[i].split('|')[1];
}
else if (output_data_lines[i].split('|')[0] == 'dinnerBird') {
document.getElementById('dinnerBird').checked = output_data_lines[i].split('|')[1];
}
else if (output_data_lines[i].split('|')[0] == 'dinnerSoup') {
document.getElementById('dinnerSoup').checked = output_data_lines[i].split('|')[1];
}
}
}
fr.readAsText(this.files[0]);
})
</script>
<!-- import data -->
<script>
let saveFile = () => {
// Get the data from each element on the form.
<!-- Elite Member Info -->
const Name = document.getElementById('Name').textContent;
const DoB = document.getElementById('DoB').value;
const Gender = document.getElementById('Gender').value;
const City = document.getElementById('City').value;
<!-- PROBLEM -->
<!-- Snack Preferences -->
const cheeseLover = document.getElementById('cheeseLover').checked;
const milkLover = document.getElementById('milkLover').checked;
<!-- PROBLEM -->
<!-- Dinner Preferences -->
const dinnerPizza = document.getElementById('dinnerPizza').checked;
const dinnerSalad = document.getElementById('dinnerSalad').checked;
const dinnerBird = document.getElementById('dinnerBird').checked;
const dinnerSoup = document.getElementById('dinnerSoup').checked;
// This variable stores all the data.
let data =
'Name|' + Name + '\n' +
'DoB|' + DoB + '\n' +
'Gender|' + Gender + '\n' +
'City|' + City + '\n' +
'cheeseLover|' + cheeseLover + '\n' +
'milkLover|' + milkLover + '\n' +
'dinnerPizza|' + dinnerPizza + '\n' +
'dinnerSalad|' + dinnerSalad + '\n' +
'dinnerBird|' + dinnerBird + '\n' +
'dinnerSoup|' + dinnerSoup
;
// Convert the text to BLOB.
const textToBLOB = new Blob([data], { type: 'text/plain' });
const sFileName = 'formData.txt'; // The file to save the data.
let newLink = document.createElement("a");
newLink.download = sFileName;
if (window.webkitURL != null) {
newLink.href = window.webkitURL.createObjectURL(textToBLOB);
}
else {
newLink.href = window.URL.createObjectURL(textToBLOB);
newLink.style.display = "none";
document.body.appendChild(newLink);
}
newLink.click();
}
</script>
</body>
</html>
最佳答案
这是字符串/ bool 解析的问题。
这是您当前代码的示例:
document.getElementById('milkLover').checked = output_data_lines[i].split('|')[1];
这有效地转化为这一点,这是不正确的:document.getElementById('milkLover').checked = 'false';
应该是这个,一个 bool 值:document.getElementById('milkLover').checked = false;
'checked' 属性正在寻找一个 bool 值,但您传递的是一个字符串。任何不是 0、false 或对持有其中任何一个的对象的引用都将自动传递为 true。您需要将输入从字符串解析为 bool 值。您可以使用类似这样的方法非常简单地做到这一点(据我所知,这是在 Javascript 中将字符串解析为 bool 值的唯一方法):var isTrueSet = (output_data_lines[i].split('|')[1] === 'true');
document.getElementById('milkLover').checked = isTrueSet;
如果您使用此临时变量将所有字符串解析为复选框或单选字段的每个“if”语句中的 bool 值,您的代码将完美运行 - as seen here
关于javascript - HTML/JS 表单无法正确导入/导出 txt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68124008/