克隆时将数据记录到适当的 html children 元素
Record data to proper html children elements when cloning
我在 Google sheet 中有一个表格,我从 sheet.
发送动态数据
我循环 sheet 数据并在表单中创建与我的 headers.
相同数量的块
我用 html 编写了第一个元素块。
我从第一个块克隆的其余块,克隆其 ID 并将我的 sheet 标题发送到表单元素。
我写的第一个标题(带有数组中的最后一个标题)到循环之前唯一存在的块。
然后我克隆该块,为克隆提供新标题并尝试在第一个块 ([0]) 之前插入克隆,但它出错了,覆盖了我的第一个硬编码标题。
它以随机数附加块,所以我无法按照正确的顺序获得我的标题,如“1,2,3”。
它总是像“2,1,1”或“1,3,2”等
我尝试了附加克隆元素的不同变体(如 motherDiv.appendChild(clonedRow)
和 motherDiv.insertBefore(clonedRow, motherDiv.children[0])
,但无法正常工作。
请指出这里有什么问题。
这是代码和屏幕:
//my google app backend function with data
var numbers = [1, 2, 3]
var stats = ["Валовый доход", "Кол-во клиентов", "Кол-во размещенной рекламы"]
var stats = {
statNumbers: numbers,
statStats: stats
}
//select initialization
document.addEventListener('DOMContentLoaded', function() {
var getstats = getStats();
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems);
});
//getting stats object
function getStats() {
google.script.run.withSuccessHandler(processStats).statsObj();
google.script.run.withFailureHandler(showError).statsObj()
return;
}
//creating dynamic stats fields in the form
function processStats(stats) {
//name first statistic with the last number
var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[stats.statStats.length - 1] + ". " + stats.statStats[stats.statStats.length - 1]
//mother div
var motherDiv = document.getElementById("motherDiv")
//sample row to copy
var statRow = document.getElementById("statsample");
//loop stat names
for (var i = 0; i < stats.statStats.length - 1; i++) {
var statName = stats.statStats[i]
var statNumber = stats.statNumbers[i]
//cloning the original row
var clonedRow = statRow.cloneNode(true)
//setting unique ID to whole row
var rowId = clonedRow.id = "statsample" + i
//setting unique ID to stat div
var clonedStatID = motherDiv.getElementsByClassName("statClass")[0].id = "statName" + statNumber
//stat titles (except first one)
var statHtml = document.getElementById(clonedStatID).innerHTML = statNumber + ". " + statName;
var err = document.getElementById("err").innerHTML = motherDiv.children.length
//appending it to the mother div
//motherDiv.appendChild(clonedRow);
motherDiv.insertBefore(clonedRow, motherDiv.children[0]);
}
return;
}
function showError() {
var err = document.getElementById("err").innerHTML = "There was an error."
}
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<div id="motherDiv">
<!-- mother div -->
<div class="row" id="statsample">
<div class=" input-field col s3 #fffde7 yellow lighten-5">
<h6 id="statName" class="statClass"></h6>
</div>
<div class="input-field col s3">
<select class="icons browser-default" id="weeksSel4">
<option value="" disabled selected>Неделя</option>
</select>
</div>
<div class="input-field col s2">
<input id="numbers" type="text" class="validate">
<label for="numbers">Значение</label>
</div>
<div class="input-field col s1.5">
<select class="icons browser-default" id="measure">
<option value="" disabled selected>Ед. изм:</option>
<option value="">шт.</option>
<option value="">%</option>
<option value="">$</option>
<option value="">руб.</option>
<option value="">грн.</option>
</select>
</div>
<div class="input-field col s2.5">
<a class="waves-effect waves-light btn-small #039be5 light-blue darken-1" style="float: right;" id="btn1row"><i class="material-icons right">send</i>Ввести</a>
</div>
</div>
<!-- row end -->
</div>
<!-- mother div end-->
<div id="err"> </div>
我建议用数组的第一个元素填充 'master' div 并且克隆从索引 1 开始遍历数组。
我们需要对您的 processStats(stats)
函数进行一些根本性的更改。
首先填充master:
var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[0] + ". " + stats.statStats[0];
下面两行没有改动
var motherDiv = document.getElementById("motherDiv")
var statRow = document.getElementById("statsample");
将for循环改为从1开始
for (var i = 1; i < stats.statStats.length; i++) {
}
现在 for-loop 本身需要一些更改。
这三行没问题
var statName = stats.statStats[i];
var statNumber = stats.statNumbers[i];
var clonedRow = statRow.cloneNode(true);
下面是我没看懂的
var clonedStatID = motherDiv.getElementsByClassName("statClass")[0].id = "statName" + statNumber
我知道你想给新克隆的 divs child statClass 一个带有序列号的唯一 ID,但每次迭代 for-loop 这将为列表中的第一个元素提供 id。上面你已经有一个变量,它包含对克隆 div clonedRow 的引用,你也可以使用它来访问它的 children.
所以摆脱这条线并使用这个:
clonedRow.getElementsByTagName("h6")[0].innerHTML = statNumber + ". " + statName;
现在只需将 div 附加到 parent
motherDiv.appendChild(clonedRow);
这是一个工作示例 - 只需单击 'Run code snippet' 即可查看实际效果:
//my google app backend function with data
var numbers = [1, 2, 3]
var stats = ["Валовый доход", "Кол-во клиентов", "Кол-во размещенной рекламы"]
var stats = {
statNumbers: numbers,
statStats: stats
}
function processStats(stats) {
//name first statistic with the last number
var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[0] + ". " + stats.statStats[0];
//mother div
var motherDiv = document.getElementById("motherDiv")
//sample row to copy
var statRow = document.getElementById("statsample");
//loop stat names
for (var i = 1; i < stats.statStats.length; i++) {
var statName = stats.statStats[i];
var statNumber = stats.statNumbers[i];
var clonedRow = statRow.cloneNode(true);
var rowId = clonedRow.id = "statsample" + i;
clonedRow.getElementsByTagName("h6")[0].innerHTML = statNumber + ". " + statName;
var err = document.getElementById("err").innerHTML = motherDiv.children.length
motherDiv.appendChild(clonedRow);
}
return;
}
function showError() {
var err = document.getElementById("err").innerHTML = "There was an error."
}
processStats(stats);
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<div id="motherDiv">
<!-- mother div -->
<div class="row" id="statsample">
<div class=" input-field col s3 #fffde7 yellow lighten-5">
<h6 id="statName" class="statClass"></h6>
</div>
<div class="input-field col s3">
<select class="icons browser-default" id="weeksSel4">
<option value="" disabled selected>Неделя</option>
</select>
</div>
<div class="input-field col s2">
<input id="numbers" type="text" class="validate">
<label for="numbers">Значение</label>
</div>
<div class="input-field col s1.5">
<select class="icons browser-default" id="measure">
<option value="" disabled selected>Ед. изм:</option>
<option value="">шт.</option>
<option value="">%</option>
<option value="">$</option>
<option value="">руб.</option>
<option value="">грн.</option>
</select>
</div>
<div class="input-field col s2.5">
<a class="waves-effect waves-light btn-small #039be5 light-blue darken-1" style="float: right;" id="btn1row"><i class="material-icons right">send</i>Ввести</a>
</div>
</div>
<!-- row end -->
</div>
<!-- mother div end-->
<div id="err"> </div>
我在 Google sheet 中有一个表格,我从 sheet.
发送动态数据我循环 sheet 数据并在表单中创建与我的 headers.
相同数量的块我用 html 编写了第一个元素块。 我从第一个块克隆的其余块,克隆其 ID 并将我的 sheet 标题发送到表单元素。
我写的第一个标题(带有数组中的最后一个标题)到循环之前唯一存在的块。
然后我克隆该块,为克隆提供新标题并尝试在第一个块 ([0]) 之前插入克隆,但它出错了,覆盖了我的第一个硬编码标题。
它以随机数附加块,所以我无法按照正确的顺序获得我的标题,如“1,2,3”。 它总是像“2,1,1”或“1,3,2”等
我尝试了附加克隆元素的不同变体(如 motherDiv.appendChild(clonedRow)
和 motherDiv.insertBefore(clonedRow, motherDiv.children[0])
,但无法正常工作。
请指出这里有什么问题。
这是代码和屏幕:
//my google app backend function with data
var numbers = [1, 2, 3]
var stats = ["Валовый доход", "Кол-во клиентов", "Кол-во размещенной рекламы"]
var stats = {
statNumbers: numbers,
statStats: stats
}
//select initialization
document.addEventListener('DOMContentLoaded', function() {
var getstats = getStats();
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems);
});
//getting stats object
function getStats() {
google.script.run.withSuccessHandler(processStats).statsObj();
google.script.run.withFailureHandler(showError).statsObj()
return;
}
//creating dynamic stats fields in the form
function processStats(stats) {
//name first statistic with the last number
var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[stats.statStats.length - 1] + ". " + stats.statStats[stats.statStats.length - 1]
//mother div
var motherDiv = document.getElementById("motherDiv")
//sample row to copy
var statRow = document.getElementById("statsample");
//loop stat names
for (var i = 0; i < stats.statStats.length - 1; i++) {
var statName = stats.statStats[i]
var statNumber = stats.statNumbers[i]
//cloning the original row
var clonedRow = statRow.cloneNode(true)
//setting unique ID to whole row
var rowId = clonedRow.id = "statsample" + i
//setting unique ID to stat div
var clonedStatID = motherDiv.getElementsByClassName("statClass")[0].id = "statName" + statNumber
//stat titles (except first one)
var statHtml = document.getElementById(clonedStatID).innerHTML = statNumber + ". " + statName;
var err = document.getElementById("err").innerHTML = motherDiv.children.length
//appending it to the mother div
//motherDiv.appendChild(clonedRow);
motherDiv.insertBefore(clonedRow, motherDiv.children[0]);
}
return;
}
function showError() {
var err = document.getElementById("err").innerHTML = "There was an error."
}
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<div id="motherDiv">
<!-- mother div -->
<div class="row" id="statsample">
<div class=" input-field col s3 #fffde7 yellow lighten-5">
<h6 id="statName" class="statClass"></h6>
</div>
<div class="input-field col s3">
<select class="icons browser-default" id="weeksSel4">
<option value="" disabled selected>Неделя</option>
</select>
</div>
<div class="input-field col s2">
<input id="numbers" type="text" class="validate">
<label for="numbers">Значение</label>
</div>
<div class="input-field col s1.5">
<select class="icons browser-default" id="measure">
<option value="" disabled selected>Ед. изм:</option>
<option value="">шт.</option>
<option value="">%</option>
<option value="">$</option>
<option value="">руб.</option>
<option value="">грн.</option>
</select>
</div>
<div class="input-field col s2.5">
<a class="waves-effect waves-light btn-small #039be5 light-blue darken-1" style="float: right;" id="btn1row"><i class="material-icons right">send</i>Ввести</a>
</div>
</div>
<!-- row end -->
</div>
<!-- mother div end-->
<div id="err"> </div>
我建议用数组的第一个元素填充 'master' div 并且克隆从索引 1 开始遍历数组。
我们需要对您的 processStats(stats)
函数进行一些根本性的更改。
首先填充master:
var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[0] + ". " + stats.statStats[0];
下面两行没有改动
var motherDiv = document.getElementById("motherDiv")
var statRow = document.getElementById("statsample");
将for循环改为从1开始
for (var i = 1; i < stats.statStats.length; i++) {
}
现在 for-loop 本身需要一些更改。 这三行没问题
var statName = stats.statStats[i];
var statNumber = stats.statNumbers[i];
var clonedRow = statRow.cloneNode(true);
下面是我没看懂的
var clonedStatID = motherDiv.getElementsByClassName("statClass")[0].id = "statName" + statNumber
我知道你想给新克隆的 divs child statClass 一个带有序列号的唯一 ID,但每次迭代 for-loop 这将为列表中的第一个元素提供 id。上面你已经有一个变量,它包含对克隆 div clonedRow 的引用,你也可以使用它来访问它的 children.
所以摆脱这条线并使用这个:
clonedRow.getElementsByTagName("h6")[0].innerHTML = statNumber + ". " + statName;
现在只需将 div 附加到 parent
motherDiv.appendChild(clonedRow);
这是一个工作示例 - 只需单击 'Run code snippet' 即可查看实际效果:
//my google app backend function with data
var numbers = [1, 2, 3]
var stats = ["Валовый доход", "Кол-во клиентов", "Кол-во размещенной рекламы"]
var stats = {
statNumbers: numbers,
statStats: stats
}
function processStats(stats) {
//name first statistic with the last number
var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[0] + ". " + stats.statStats[0];
//mother div
var motherDiv = document.getElementById("motherDiv")
//sample row to copy
var statRow = document.getElementById("statsample");
//loop stat names
for (var i = 1; i < stats.statStats.length; i++) {
var statName = stats.statStats[i];
var statNumber = stats.statNumbers[i];
var clonedRow = statRow.cloneNode(true);
var rowId = clonedRow.id = "statsample" + i;
clonedRow.getElementsByTagName("h6")[0].innerHTML = statNumber + ". " + statName;
var err = document.getElementById("err").innerHTML = motherDiv.children.length
motherDiv.appendChild(clonedRow);
}
return;
}
function showError() {
var err = document.getElementById("err").innerHTML = "There was an error."
}
processStats(stats);
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<div id="motherDiv">
<!-- mother div -->
<div class="row" id="statsample">
<div class=" input-field col s3 #fffde7 yellow lighten-5">
<h6 id="statName" class="statClass"></h6>
</div>
<div class="input-field col s3">
<select class="icons browser-default" id="weeksSel4">
<option value="" disabled selected>Неделя</option>
</select>
</div>
<div class="input-field col s2">
<input id="numbers" type="text" class="validate">
<label for="numbers">Значение</label>
</div>
<div class="input-field col s1.5">
<select class="icons browser-default" id="measure">
<option value="" disabled selected>Ед. изм:</option>
<option value="">шт.</option>
<option value="">%</option>
<option value="">$</option>
<option value="">руб.</option>
<option value="">грн.</option>
</select>
</div>
<div class="input-field col s2.5">
<a class="waves-effect waves-light btn-small #039be5 light-blue darken-1" style="float: right;" id="btn1row"><i class="material-icons right">send</i>Ввести</a>
</div>
</div>
<!-- row end -->
</div>
<!-- mother div end-->
<div id="err"> </div>