首页 > 解决方案 > 循环遍历具有相同类的动态生成的 HTML 元素并使用它们的数据构建对象

问题描述

我正在尝试从单击按钮时动态生成的表中收集数据。正如您将在下面看到的,该按钮创建了一个新的文本框和一个多选下拉菜单。目前,我的代码只会从文本框和下拉列表中获取第一个值。

我的最终目标是创建一个如下所示的键/值对象:

{"group 1":[multiselect value, multiselect value], "group 2": [multiselect value, multiselect value, multiselect value], "group 3": [multiselect value, multiselect value]}

以下是我当前的代码。任何指导表示赞赏!

function servicePackageAdd()
{
    
    var serviceName = document.getElementById('servicePackageText').value;

    var serviceList = document.querySelectorAll('.service');
    
    var serviceGroupName = [];
    
    for (var i = 0; i < serviceList.length; i++)
    {
        
        serviceGroupName.push(serviceList[i].querySelector('input.packageGroupName').value);

        var sourceType = document.querySelector('select#multiple-checkboxes');


            var serviceArray = [];
            for (i = 0; i < sourceType.selectedOptions.length; i++)
            {
                serviceArray.push(parseInt(sourceType.selectedOptions[i].value));
            }
            var groupName = {};
            groupName[serviceGroupName] = serviceArray;
            ungroupedServiceArray = [];
     }
}



document.getElementById('addGroup').onclick = duplicate;
  
function duplicate() 
{    
    var original = document.getElementById('addService');
    var rows = original.parentNode.rows;
    var i = rows.length - 1;
    var clone = original.cloneNode(true); // "deep" clone
    clone.id = "duplic" + (i); // there can only be one element with an ID
    original.parentNode.insertBefore(clone, rows[i]);
}

var divs = ["addService"];
var visibleDivId = null;

function toggleCheckbox(divId) 
{
    if(visibleDivId === divId) 
    {
      visibleDivId = null;
    } else 
    {
      visibleDivId = divId;
    }
    hideNonVisibleDivs();
}

function hideNonVisibleDivs() 
{
    var i, divId, div;
    for(i = 0; i < divs.length; i++) 
    {
      divId = divs[i];
      div = document.getElementById(divId);
      
      if(visibleDivId === divId) 
      {
        div.style.display = "block";
      } 
      else 
      {
        div.style.display = "none";
      }
    }
}

function servicePackageName()
{
    var servicePackageName = document.getElementById('servicePackageText').value;
    var servicePackageNameBold = servicePackageName.bold().fontcolor('#337ab7');
    document.getElementById('servicePackageInputName').innerHTML = servicePackageNameBold;

}
<div>
        <div class="servicePackageCreation">
            
        <h2><b>Service Package Administration</b></h2>
        <br>
        <span><p><b>Create Service Package: </b></p><p id="servicePackageInputName"></p></span>
            <div class="form-group">
                <input type="text" class="form-inline" id="servicePackageText" minlength= 1 placeholder="  Service Package Name" required>
                <button type="button" class="btn btn-primary" onclick="toggleCheckbox('addService'); servicePackageName();" id="addGroupsAndServices">Next</button>
            </div>
    <table>
        <tr id="addService" class="service" style="display:none">
            <td>
                <span><b>Service Group Name</b></span>
                <input type="text" name="servicetype" id="packageGroupName" class="packageGroupName"/>
            </td>
            <td>
                <span><b>Add Services</b></span>
                <select id="multiple-checkboxes" multiple="multiple">
                    <?php echo $servicehtml ?>
                </select>
            </td>
        </tr>
        <tr>
            <td>
                <button id="addGroup" class="btn btn-primary" onclick="duplicate()">Add More</button>
            </td>
        </tr>
    </table>
    <button type="button" class="btn btn-success test1234" onclick="confirmAddButton()" id="adminBulkConfirm">Create</button>
    <br>
    <br>
</div>

标签: javascript

解决方案


使用 Object.values Array#map 和 Array#reduce。

const services = document.querySelectorAll(".service");

const res = Object.values(services)
  .map((service, i) => {
    const inputText = service.querySelector('.packageGroupName').value;
    return {
      [inputText]: [...service.querySelectorAll('option:checked')].map(o => Number(o.value))
    }
  })
  .reduce((a, c) => ({ ...a,...c}), {});

console.log(res);
table {
  display: none;
}
<table>
  <tr class="service">
    <td>
      <span><b>Service Group Name</b></span>
      <input type="text" name="servicetype" id="packageGroupName" class="packageGroupName" value="Banana" />
    </td>
    <td>
      <span><b>Add Services</b></span>
      <select class="multiple-checkboxes" multiple="multiple">
        <option value="1" selected>12</option>
      </select>
    </td>
  </tr>
  <tr class="service">
    <td>
      <span><b>Service Group Name</b></span>
      <input type="text" name="servicetype" id="packageGroupName" class="packageGroupName" value="Orange" />
    </td>
    <td>
      <span><b>Add Services</b></span>
      <select class="multiple-checkboxes" multiple>
        <option value="2" selected>2</option>
        <option value="3" selected>3</option>
        <option value="4">4</option>

      </select>
    </td>
  </tr>
  <tr>
    <td>
      <button class="btn btn-primary" onclick="duplicate()">Add More</button>
    </td>
  </tr>
</table>


推荐阅读