При клонировании записывать данные в соответствующие дочерние элементы - PullRequest
0 голосов
/ 25 июня 2019

У меня есть форма на листах Google, куда я отправляю динамические данные с листа.

Я зацикливаю данные листа и создаю в форме то же количество блоков, что и количество моих заголовков.

У меня есть первый блок элементов, написанных на HTML.Остальные блоки я клонирую из первого, клонирую его идентификаторы и отправляю заголовки своих листов в элементы формы.

Первый записываемый заголовок (с последним заголовком из массива) в единственный существующий ранее блокlooping.

Затем я клонирую этот блок, давая клону новые заголовки, и пытаюсь вставить клоны перед первым блоком ([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>

enter image description here

1 Ответ

1 голос
/ 28 июня 2019

Я бы порекомендовал заполнить 'master' div первым элементом массива, и клоны начнут перебирать массив с индекса 1. Нам нужно внести некоторые фундаментальные изменения в вашу processStats(stats) функцию. Сначала заполните мастер:

  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 нуждается в некоторых изменениях. Эти три строки в порядке

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 statClass уникальный идентификатор с порядковым номером, но с каждой итерацией цикла for это даст первому элементу в списке идентификатор. Выше у вас уже есть переменная, которая содержит ссылку на клонированный div clonedRow , который вы также можете использовать для доступа к его дочерним элементам.

Так что избавьтесь от строки и используйте это:

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

Теперь просто добавьте div к родителю

motherDiv.appendChild(clonedRow);

Вот рабочий пример - просто нажмите «Запустить фрагмент кода», чтобы увидеть его в действии:

//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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...