You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTML嵌套循环中外层循环值获取及弹窗唯一ID实现方案

问题说明

当前弹窗ID重复,仅首个Project内的Edit按钮能正常生效。现有层级结构为:

PROJECT NAME
   --> ORDER NUMBER
      --> LINE ITEM
      --> LINE ITEM
   --> ORDER NUMBER
      --> LINE ITEM
      --> LINE ITEM

现有代码通过内层loop.index生成弹窗ID,导致不同Project、Order下的Line Item会出现重复ID,从而引发按钮失效问题。需要结合外层循环值生成唯一ID,同时寻求更优实现方案。

原代码片段:

{% for project in projects %}
  ...

  {% for order in project.orders %}
    ...
    
    {% for lineItem in order.line_items %}
    <td>
      <button onclick="editRow(this, '{{ loop.index }}'), openPopup('{{ loop.index }}')" class="remove-button" style="background: #00e50b">Edit</button>
      <div class="popup" id="popup{{ loop.index }}">
        <div class="popup-content">
          <h2 style='color: #000000'>Edit New ETA / Comments</h2>
          <form action="/manage_stock" method="POST" style="display: none;">
            ...
          </form>
        </div>
      </div>
    </td>
    {% endfor %}

    ...
  {% endfor %}

  ...
{% endfor %}

方案一:结合多层循环索引生成唯一ID

利用Jinja2的loop.index(或loop.index0从0开始计数),把外层循环的索引和内层索引拼接,确保每个弹窗ID唯一:

修改后的代码:

{% for project in projects %}
  {% set project_idx = loop.index %}
  ...

  {% for order in project.orders %}
    {% set order_idx = loop.index %}
    ...
    
    {% for lineItem in order.line_items %}
    {% set line_idx = loop.index %}
    {% set unique_id = project_idx ~ '-' ~ order_idx ~ '-' ~ line_idx %}
    <td>
      <button onclick="editRow(this, '{{ unique_id }}'), openPopup('{{ unique_id }}')" class="remove-button" style="background: #00e50b">Edit</button>
      <div class="popup" id="popup{{ unique_id }}">
        <div class="popup-content">
          <h2 style='color: #000000'>Edit New ETA / Comments</h2>
          <form action="/manage_stock" method="POST" style="display: none;">
            ...
          </form>
        </div>
      </div>
    </td>
    {% endfor %}

    ...
  {% endfor %}

  ...
{% endfor %}

生成的弹窗ID会是popup1-1-1、popup1-1-2、popup2-1-1这类格式,彻底避免重复。


方案二:更优实现——复用单个弹窗(推荐)

如果所有弹窗的结构一致,只是填充的数据不同,没必要为每个Line Item生成独立弹窗DOM。只创建一个全局弹窗,点击按钮时动态填充数据并显示即可:

1. 页面中保留单个全局弹窗

<!-- 全局弹窗,默认隐藏 -->
<div class="popup" id="editPopup" style="display: none;">
  <div class="popup-content">
    <h2 style='color: #000000'>Edit New ETA / Comments</h2>
    <form id="editForm" action="/manage_stock" method="POST">
      <!-- 隐藏域存储当前行ID,用于提交时识别 -->
      <input type="hidden" name="line_item_id" id="lineItemId">
      <input type="text" name="eta" id="etaInput" placeholder="New ETA">
      <textarea name="comments" id="commentsInput" placeholder="Comments"></textarea>
      <button type="submit">Save</button>
    </form>
  </div>
</div>

2. 修改按钮逻辑,传递Line Item的实际数据

{% for project in projects %}
  ...

  {% for order in project.orders %}
    ...
    
    {% for lineItem in order.line_items %}
    <td>
      <button onclick="openEditPopup('{{ lineItem.id }}', '{{ lineItem.current_eta | escape }}', '{{ lineItem.comments | escape }}')" class="remove-button" style="background: #00e50b">Edit</button>
    </td>
    {% endfor %}

    ...
  {% endfor %}

  ...
{% endfor %}

3. 编写JS函数动态填充并显示弹窗

function openEditPopup(lineItemId, currentEta, comments) {
  // 填充弹窗数据
  document.getElementById('lineItemId').value = lineItemId;
  document.getElementById('etaInput').value = currentEta || '';
  document.getElementById('commentsInput').value = comments || '';
  
  // 显示弹窗
  document.getElementById('editPopup').style.display = 'block';
}

// 关闭弹窗函数
function closeEditPopup() {
  document.getElementById('editPopup').style.display = 'none';
}

这个方案的优势:

  • 减少DOM节点数量,页面加载更快
  • 从根源上避免ID重复问题,逻辑更清晰
  • 统一弹窗样式和行为,后期维护成本更低

内容的提问来源于stack exchange,提问作者Dylan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 08:03:31