Записывать данные в соответствующие дочерние элементы html при клонировании

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

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

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

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

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

Записывать данные в соответствующие дочерние элементы html при клонировании

Почему именно вы заполняете «главный» div статистика значениями из последнего элемента внутри массива и пытаетесь добавить клоны раньше? Я бы сказал, просто дайте мастеру данные из первого элемента массива, а остальные клонируйте.

obscure 28.06.2019 00:34

Я пробовал оба направления: начиная с первого и т. д. и начиная с последнего и добавляя раньше: во всех вариантах, которые я пробовал, он добавляет строки в таком случайном порядке, и я никогда не получаю 1, 2, 3.

kiki 28.06.2019 11:11
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я бы рекомендовал заполнить «главный» 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

Я знаю, что вы хотите дать только что клонированному дочернему элементу div статкласс уникальный идентификатор с порядковым номером, но с каждой итерацией цикла for это будет давать идентификатор первому элементу в списке. Выше у вас уже есть переменная, которая содержит ссылку на клонированный div клонированная строка, который вы также можете использовать для доступа к его дочерним элементам.

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

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>

Это потрясающе, спасибо! Я вижу свою ошибку сейчас. Вы полностью помогли мне в этом! Теперь все работает исправно.

kiki 29.06.2019 14:23

Нет проблем, Кики, рад, что смог помочь!

obscure 29.06.2019 17:42

Верно) не могли бы вы помочь и с этим? Я добавил туда комментарии с новыми данными stackoverflow.com/questions/56798076/…

kiki 29.06.2019 20:08

Другие вопросы по теме

Похожие вопросы