克隆时将数据记录到适当的 html 子元素 [英] Record data to proper html children elements when cloning

查看:14
本文介绍了克隆时将数据记录到适当的 html 子元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Google 表格中有一个表格,我可以在其中发送表格中的动态数据.

我循环工作表数据并在表单中创建与标题数量相同数量的块.

我有第一块用 html 编写的元素.我从第一个块克隆的其余块,克隆它的 ID 并将我的工作表标题发送到表单元素.

我写的第一个标题(带有数组中的最后一个标题)到循环前唯一存在的块.

然后我克隆该块,为克隆提供新标题并尝试在第一个块 ([0]) 之前插入克隆但它出错并覆盖我的第一个硬编码标题.

它以随机数附加块,因此我无法按照1,2,3"等正确顺序获取标题.它总是像2,1,1"或1,3,2"等.

我尝试了附加克隆元素的不同变体(例如 motherDiv.appendChild(clonedRow)motherDiv.insertBefore(clonedRow, MotherDiv.children[0]),但无法使其正常工作.

请指出这里有什么问题.

这是代码和屏幕:

//我的谷歌应用程序后端函数与数据无功数字 = [1, 2, 3]var stats = ["Валовый доход", "Кол-во клиентов", "Кол-во размещенной рекламы"]变量统计= {statNumbers:数字,statStats: 统计}//选择初始化document.addEventListener('DOMContentLoaded', function() {var getstats = getStats();var elems = document.querySelectorAll('select');var 实例 = M.FormSelect.init(elems);});//获取统计对象函数 getStats() {google.script.run.withSuccessHandler(processStats).statsObj();google.script.run.withFailureHandler(showError).statsObj()返回;}//在表单中创建动态统计字段函数 processStats(stats) {//用最后一个数字命名第一个统计数据var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[stats.statStats.length - 1] + "." + stats.statStats[stats.statStats.length - 1]//母divvar momDiv = document.getElementById("motherDiv")//要复制的样本行var statRow = document.getElementById("statsample");//循环统计名称for (var i = 0; i < stats.statStats.length - 1; i++) {var statName = stats.statStats[i]var statNumber = stats.statNumbers[i]//克隆原行var clonedRow = statRow.cloneNode(true)//将唯一ID设置为整行var rowId = clonedRow.id = "statsample" + i//为stat div设置唯一IDvar clonedStatID = momDiv.getElementsByClassName("statClass")[0].id = "statName" + statNumber//统计标题(第一个除外)var statHtml = document.getElementById(clonedStatID).innerHTML = statNumber + "." + statName;var err = document.getElementById("err").innerHTML = MotherDiv.children.length//将其附加到母div//motherDiv.appendChild(clonedRow);MotherDiv.insertBefore(clonedRow, MotherDiv.children[0]);}返回;}函数显示错误(){var err = document.getElementById("err").innerHTML = "出现错误."}

<!--导入谷歌图标字体--><link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"><!-- 编译并缩小的 CSS --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"><div id="motherDiv"><!-- 母 div --><div class="row" id="statsample"><div class=" input-field col s3 #fffde7 Yellow lighten-5"><h6 id="statName" class="statClass"></h6>

<div class="input-field col s3"><select class="icons browser-default" id="weeksSel4"><option value="" disabled selected>Неделя</option></选择>

<div class="input-field col s2"><input id="numbers" type="text" class="validate"><label for="numbers">Значение</label>

<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></选择>

<div class="input-field col s2.5"><a class="waves-effect wave-light btn-small #039be5 light-blue darken-1" style="float: right;"id="btn1row"><i class="material-icons right">发送</i>Ввести</a>

<!-- 行尾-->

<!-- 母 div 结束--><div id="错误">

解决方案

我建议使用数组的第一个元素填充主"div,并且克隆从索引 1 开始迭代数组.我们需要对您的 processStats(stats) 函数进行一些根本性的更改.首先填充master:

 var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[0] + "." + stats.statStats[0];

以下两行不变

 var momDiv = document.getElementById("motherDiv")var statRow = document.getElementById("statsample");

改变for循环从1开始

 for (var i = 1; i 

现在 for 循环本身需要一些更改.这三行没问题

var statName = stats.statStats[i];var statNumber = stats.statNumbers[i];var clonedRow = statRow.cloneNode(true);

我不明白的是以下

var clonedStatID = momDiv.getElementsByClassName("statClass")[0].id = "statName" + statNumber

我知道你想给新克隆的 divs 子 statClass 一个带有序列号的唯一 id,但是在 for 循环的每次迭代中,这会给列表中的第一个元素提供 id.上面你已经有一个变量,它包含对克隆 div clonedRow 的引用,你也可以用来访问它的子级.

所以去掉这条线并使用这个:

clonedRow.getElementsByTagName("h6")[0].innerHTML = statNumber + "." + statName;

现在只需将 div 附加到父级

motherDiv.appendChild(clonedRow);

这是一个工作示例 - 只需单击运行代码片段"即可查看其运行情况:

//我的谷歌应用程序后端函数与数据无功数字 = [1, 2, 3]var stats = ["Валовый доход", "Кол-во клиентов", "Кол-во размещенной рекламы"]变量统计= {statNumbers:数字,statStats: 统计}函数 processStats(stats) {//用最后一个数字命名第一个统计数据var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[0] + "." + stats.statStats[0];//母divvar momDiv = document.getElementById("motherDiv")//要复制的样本行var statRow = document.getElementById("statsample");//循环统计名称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.lengthMotherDiv.appendChild(clonedRow);}返回;}函数显示错误(){var err = document.getElementById("err").innerHTML = "出现错误."}processStats(stats);

<!--导入谷歌图标字体--><link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"><!-- 编译并缩小的 CSS --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"><div id="motherDiv"><!-- 母 div --><div class="row" id="statsample"><div class=" input-field col s3 #fffde7 Yellow lighten-5"><h6 id="statName" class="statClass"></h6>

<div class="input-field col s3"><select class="icons browser-default" id="weeksSel4"><option value="" disabled selected>Неделя</option></选择>

<div class="input-field col s2"><input id="numbers" type="text" class="validate"><label for="numbers">Значение</label>

<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></选择>

<div class="input-field col s2.5"><a class="waves-effect wave-light btn-small #039be5 light-blue darken-1" style="float: right;"id="btn1row"><i class="material-icons right">发送</i>Ввести</a>

<!-- 行尾-->

<!-- 母 div 结束--><div id="错误">

I have a form in Google sheets where I send dynamic data from the sheet.

I loop sheet data and create same number of blocks in a form as number of my headers.

I have a first block of elements written in html. The rest of blocks I clone from the first one, clone its IDs and send my sheet titles to elements of the form.

First title I write (with the last title from an array) to the only block existing before looping.

Then I clone that block giving a clone new titles and trying to insert clones before the first block ([0]) but it gets wrong and overwrites my first hardcoded title.

It appends the blocks in random number, so I can't get my titles in the right sequence like "1,2,3". It's always like "2,1,1" or "1,3,2" etc.

I've tried different variations of appending the cloned elements (like motherDiv.appendChild(clonedRow) and motherDiv.insertBefore(clonedRow, motherDiv.children[0]), but cannot get it to work properly.

Please point to what's wrong here.

Here's the code and the screen:

//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>

解决方案

I'd recommend populating the 'master' div with the first element of the array and for the clones start iterating over the array from index 1. We need to make some fundamental changes to your processStats(stats) function. First populate the master:

  var firstStat = document.getElementById("statName").innerHTML = stats.statNumbers[0] + ". " + stats.statStats[0];

the following two lines are untouched

  var motherDiv = document.getElementById("motherDiv")
  var statRow = document.getElementById("statsample");

Change the for loop to start from 1

  for (var i = 1; i < stats.statStats.length; i++) {
  }

Now the for-loop itself needs some changes. These three lines are okay

var statName = stats.statStats[i];
var statNumber = stats.statNumbers[i];
var clonedRow = statRow.cloneNode(true);

What I don't understand is the following

var clonedStatID = motherDiv.getElementsByClassName("statClass")[0].id = "statName" + statNumber

I know you want to give the freshly cloned divs child statClass a unique id with a sequential number but with every iteration of the for-loop this would give the first element in the list the id. Above you already have a variable which holds a reference to the cloned div clonedRow you can also use to access it's children.

So get rid of the line and use this:

clonedRow.getElementsByTagName("h6")[0].innerHTML = statNumber + ". " + statName;

Now just append the div to the parent

motherDiv.appendChild(clonedRow);

Here's a working example - just click 'Run code snippet' to see it in action:

//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>

这篇关于克隆时将数据记录到适当的 html 子元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆