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

复选框联动Report Analysis区域显隐功能实现求助

问题描述

当前Issue区域的选中复选框及Report Analysis数据均从数据库读取。需求是:取消任意复选框勾选时,Report Analysis区域对应隐藏一组数据;勾选新复选框时,新增一组Report Analysis输入项。现有代码未实现该功能,请求修复。

问题诊断

现有代码存在以下核心问题:

  • 每次触发showAnalysisDropdowns都会清空容器后全量重建输入组,无法实现单个复选框对应单个分析组的精准控制
  • PHP渲染的历史分析数据与JS生成的新数据分属不同容器,两者无关联,导致勾选状态无法对应到具体数据组
  • 复选框重复绑定事件,存在逻辑冲突
  • 生成的输入组未与复选框ID关联,无法追踪对应关系
修复方案

1. 调整HTML结构,统一数据容器

将历史分析数据移入#analysisContainer,并给每个分析组添加与复选框对应的data-issue-id标识:

<table>
  <tr>
    <td><b> Issue : </b></td>
    <td>
      <?php
        $sql = "SELECT issue_id FROM tblccrs_details WHERE complaintId='" . $_GET['cid'] . "'";
        $result = mysqli_query($con, $sql);

        $issueIdsFromDatabase = array();
        while ($row = mysqli_fetch_array($result)) {
            $explodedList = explode(',', $row['issue_id']);
            $issueIdsFromDatabase = array_merge($issueIdsFromDatabase, $explodedList);
        }
        $issueIdsFromDatabase = array_unique($issueIdsFromDatabase);

        $issue = mysqli_query($con, "SELECT * FROM list_issue_ts where issue_ts_status='1'");
        while ($row = mysqli_fetch_array($issue)) {
            $issueId = $row['issue_id'];
            $issueDesc = $row['issue_ts_desc'];
            $isChecked = in_array($issueId, $issueIdsFromDatabase);
            echo '<input type="checkbox" name="selectedIssues[]" value="' . $issueId . '" ' . ($isChecked ? 'checked' : '') . '> ' . $issueDesc . '<br>';
        }
      ?>
    </td>
  </tr>

  <tr height="50">
    <td colspan="2"> <b>Report Analysis : </b> </td>
  </tr>

  <tr>
    <td colspan="2">
      <div id="analysisContainer">
        <?php
          $a = 1;
          $sql = "SELECT analysis_desc, analysis_sampleNo, analysis_result, analysis_total, issue_id FROM tblccrs_report_analysis WHERE complaintId='" . $_GET['cid'] . "'";
          $result = mysqli_query($con, $sql);
          while ($row = mysqli_fetch_array($result)) { 
              $analysisDesc = $row['analysis_desc'];
        ?>
        <div class="analysis-group" data-issue-id="<?php echo $row['issue_id']; ?>">
          <label><?php echo $a; ?>. </label>
          <select name="analysis_data[]" onchange="calculateAnalysisTotal(this)">
            <?php
              $allAnalysisQuery = "SELECT DISTINCT analysis_desc, analysis_value FROM list_report_analysis WHERE analysis_status='1'";
              $allAnalysisResult = mysqli_query($con, $allAnalysisQuery);
              while ($descRow = mysqli_fetch_assoc($allAnalysisResult)) {
                  $selected = ($descRow['analysis_desc'] == $analysisDesc) ? "selected" : "";
                  echo '<option value="' . $descRow['analysis_value'] . '" data-analysis-desc="' . $descRow['analysis_desc'] . '" ' . $selected . '>'
                      . $descRow['analysis_desc'] . '</option>';
              }
            ?>
          </select>
          <br> Sample No: <input type="text" name="analysis_sampleNo[]" value="<?php echo $row['analysis_sampleNo']; ?>">
          <br> Result: <input type="text" name="analysis_result[]" value="<?php echo htmlentities(number_format($row['analysis_result'], 2)); ?>">
          <br> Exceed: <input type="text" name="analysis_total[]" value="<?php echo htmlentities(number_format($row['analysis_total'], 2)); ?>" readonly>
          <br>
          <button type="button" onclick="calculateAnalysisTotal(this)">Calculate</button>
          <br />
          <hr />
        </div>
        <?php $a++;} ?>
      </div>
    </td>
  </tr>
</table>

2. 重写JS逻辑,实现复选框与分析组的精准关联

针对单个复选框的变化,仅操作对应的分析组(显示/隐藏/创建):

document.addEventListener('DOMContentLoaded', function() {
  const issueCheckboxes = document.querySelectorAll('input[name="selectedIssues[]"]');
  const analysisContainer = document.getElementById('analysisContainer');
  
  // 预加载分析选项数据
  const analysisOptions = <?php
    $analysis = mysqli_query($con, "SELECT analysis_desc, analysis_value FROM list_report_analysis where analysis_status='1'");
    $options = array();
    while ($row = mysqli_fetch_array($analysis)) {
        $options[] = [
            'desc' => $row['analysis_desc'],
            'value' => $row['analysis_value']
        ];
    }
    echo json_encode($options);
  ?>;

  // 初始化:隐藏未勾选复选框对应的分析组
  issueCheckboxes.forEach(checkbox => {
    const issueId = checkbox.value;
    const existingGroup = analysisContainer.querySelector(`.analysis-group[data-issue-id="${issueId}"]`);
    if (!checkbox.checked && existingGroup) {
      existingGroup.style.display = 'none';
    }
    checkbox.addEventListener('change', handleCheckboxChange);
  });

  function handleCheckboxChange(e) {
    const checkbox = e.target;
    const issueId = checkbox.value;
    let analysisGroup = analysisContainer.querySelector(`.analysis-group[data-issue-id="${issueId}"]`);

    if (checkbox.checked) {
      if (analysisGroup) {
        analysisGroup.style.display = 'block';
      } else {
        analysisGroup = createNewAnalysisGroup(issueId);
        analysisContainer.appendChild(analysisGroup);
      }
    } else {
      if (analysisGroup) {
        analysisGroup.style.display = 'none';
      }
    }

    // 控制容器整体显示状态
    analysisContainer.style.display = document.querySelector('input[name="selectedIssues[]"]:checked') ? 'block' : 'none';
  }

  // 创建新分析组
  function createNewAnalysisGroup(issueId) {
    const groupDiv = document.createElement('div');
    groupDiv.className = 'analysis-group';
    groupDiv.setAttribute('data-issue-id', issueId);

    // 生成下拉选择框
    const select = document.createElement('select');
    select.name = 'analysis_data[]';
    select.innerHTML = '<option value="">Select Report Analysis</option>';
    analysisOptions.forEach(opt => {
      const option = document.createElement('option');
      option.value = opt.value;
      option.textContent = opt.desc;
      option.setAttribute('data-analysis-desc', opt.desc);
      select.appendChild(option);
    });
    select.addEventListener('change', calculateAnalysisTotal);

    // 生成输入框
    const sampleNoInput = document.createElement('input');
    sampleNoInput.type = 'text';
    sampleNoInput.name = 'analysis_sampleNo[]';
    sampleNoInput.placeholder = 'Sample No';

    const resultInput = document.createElement('input');
    resultInput.type = 'text';
    resultInput.name = 'analysis_result[]';
    resultInput.placeholder = 'Result';

    const totalInput = document.createElement('input');
    totalInput.type = 'text';
    totalInput.name = 'analysis_total[]';
    totalInput.placeholder = 'Total Exceed';
    totalInput.readOnly = true;

    // 生成计算按钮
    const calcBtn = document.createElement('button');
    calcBtn.type = 'button';
    calcBtn.textContent = 'Calculate';
    calcBtn.addEventListener('click', calculateAnalysisTotal);

    // 组装元素
    groupDiv.appendChild(select);
    groupDiv.appendChild(document.createElement('br'));
    groupDiv.appendChild(document.createTextNode('Sample No: '));
    groupDiv.appendChild(sampleNoInput);
    groupDiv.appendChild(document.createElement('br'));
    groupDiv.appendChild(document.createTextNode('Result: '));
    groupDiv.appendChild(resultInput);
    groupDiv.appendChild(document.createElement('br'));
    groupDiv.appendChild(document.createTextNode('Exceed: '));
    groupDiv.appendChild(totalInput);
    groupDiv.appendChild(document.createElement('br'));
    groupDiv.appendChild(calcBtn);
    groupDiv.appendChild(document.createElement('br'));
    groupDiv.appendChild(document.createElement('hr'));

    return groupDiv;
  }
});

// 计算超出值函数
function calculateAnalysisTotal(e) {
  const group = e.target.closest('.analysis-group');
  if (!group) return;

  const select = group.querySelector('select');
  const resultInput = group.querySelector('input[name="analysis_result[]"]');
  const totalInput = group.querySelector('input[name="analysis_total[]"]');

  const analysisValue = parseFloat(select.value) || 0;
  const result = parseFloat(resultInput.value) || 0;
  
  // 此处可根据实际业务逻辑修改计算方式
  totalInput.value = (result - analysisValue).toFixed(2);
}

3. 关键修改说明

  • 关联标识:通过data-issue-id绑定复选框与分析组,实现一一对应
  • 精准操作:单个复选框变化时仅处理对应分析组,避免全量重建
  • 数据预加载:提前将分析选项转为JSON格式传入JS,提升性能
  • 统一容器:将历史数据与新增数据纳入同一容器,便于管理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 16:15:57