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

AJAX调用与图表加载时Bootstrap下拉框消失问题求助

问题

执行AJAX调用或首次加载图表时,HTML中用Bootstrap定义的下拉框所在区域会消失。

相关代码

HTML代码

<div class="col-md-6">
  <h2>Certificates Report using Google Chart</h2>
  <div id="certificate-container">
    <div class="form-group">
      <div class="col-md-4">
        <label for="days_cert">Interval:</label>
        <select name="days" id="days_cert" class="form-control table-filter">
          <option value="1">1 day ago</option>
          <option value="7">7 days ago</option>
          <option value="30">1 month ago</option>
          <option value="90">3 month ago</option>
          <option value="365" selected>1 year ago</option>
          <option value="730">2 year ago</option>
        </select>
      </div>
    </div>
    <div id="chart-container">
      <div id="chart_div"></div>
      <div id="piechart" style="width: 500px; height: 300px;"></div>
    </div>
  </div>
</div>

JavaScript代码

var real_data;
var real_data_payment;
var real_data_enrollment;
var requestInput;
var dataCert;
var requestInputPay;
var dataPay;
var requestInputEnroll;
var dataEnroll;

days_cert.addEventListener('change', function() {
  requestInput = new RequestInput($("#days_cert").val());
  dataCert = JSON.stringify(requestInput);
  updateChartDataCertificate();
  loadCharts();
});

requestInput = new RequestInput($("#days_cert").val());
dataCert = JSON.stringify(requestInput);
function updateChartDataCertificate() {
  $.ajax({
    type: 'POST',
    url: '/api/charts/certificates/count',
    data: dataCert,
    contentType: "application/json",
    dataType: "json",
    success: function(response) {
      console.log(dataCert);
      real_data = response;
      console.log(real_data);
    },
    error: function(xhr, status, error) {
      var requestInput = new RequestInput($("#days_cert").val());
      console.log(JSON.stringify(requestInput));
    }
  });
}

$(document).ready(function() {
  updateChartDataCertificate();
  loadCharts();
});
function loadCharts() {
  google.charts.load('current', {
    packages : [ 'corechart', 'bar' ]
  });
  google.charts.setOnLoadCallback(drawColumnChart);
  google.charts.setOnLoadCallback(drawPieChart);
}
function RequestInput(days) {
  this.days = days;
}
function drawColumnChart() {
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Type');
  data.addColumn('number', 'Count');
  console.log(real_data);
  Object.keys(real_data).forEach(function(key) {
    data.addRow([ key, real_data[key] ]);
  });
  var options = {
    title : 'Certificate Stats',
    chartArea: {
      bottom: 40
    },
    hAxis : {
      title : 'Type',
      textStyle: {
        fontSize: 8,
        fontStyle: "Arial",
        marginTop: '25'
      }
    },
    vAxis : {
      title : 'Count'
    }
  };
  var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
  chart.draw(data, options);
}
function drawPieChart() {
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Type');
  data.addColumn('number', 'Count');
  Object.keys(real_data).forEach(function(key) {
    data.addRow([ key, real_data[key] ]);
  });
  var options = {
    title : 'Certificate Stats',
    is3D: true,
    pieSliceTextStyle: {
      fontSize: 8
    }
  };
  var chart = new google.visualization.PieChart(document.getElementById('piechart'));
  chart.draw(data, options);
}

现象说明

  • 操作前:下拉框正常显示,图表区域未完全渲染
  • 操作后:下拉框所在区域消失,仅图表区域保留

解决方案

问题根源

  1. 重复加载Google Charts:每次下拉框变化或页面加载时都调用google.charts.load(),该方法会重置页面部分DOM结构,导致下拉框被意外清除。
  2. 异步请求时序错误:AJAX请求是异步的,调用updateChartDataCertificate()后立刻执行loadCharts(),此时real_data还未更新,不仅图表会出错,还会触发重复加载逻辑。
  3. Bootstrap布局嵌套错误:form-group与栅格列col-md-4的嵌套不符合Bootstrap规范,容易被图表渲染的样式干扰。

修改步骤

1. 调整JavaScript代码,避免重复加载Google Charts

将Google Charts的加载逻辑移到全局,仅执行一次;并将图表绘制逻辑放到AJAX请求的成功回调中,确保数据更新后再渲染图表。

修改后的JavaScript代码:

var real_data;
var real_data_payment;
var real_data_enrollment;
var requestInput;
var dataCert;
var requestInputPay;
var dataPay;
var requestInputEnroll;
var dataEnroll;

// 仅加载一次Google Charts
google.charts.load('current', {
  packages: ['corechart', 'bar']
});
// 加载完成后初始化数据和图表
google.charts.setOnLoadCallback(function() {
  requestInput = new RequestInput($("#days_cert").val());
  dataCert = JSON.stringify(requestInput);
  updateChartDataCertificate();
});

// 下拉框变化时仅触发数据请求
days_cert.addEventListener('change', function() {
  requestInput = new RequestInput($("#days_cert").val());
  dataCert = JSON.stringify(requestInput);
  updateChartDataCertificate();
});

function updateChartDataCertificate() {
  $.ajax({
    type: 'POST',
    url: '/api/charts/certificates/count',
    data: dataCert,
    contentType: "application/json",
    dataType: "json",
    success: function(response) {
      real_data = response;
      // 数据更新后直接绘制图表
      drawColumnChart();
      drawPieChart();
    },
    error: function(xhr, status, error) {
      var requestInput = new RequestInput($("#days_cert").val());
      console.log(JSON.stringify(requestInput));
    }
  });
}

function RequestInput(days) {
  this.days = days;
}

function drawColumnChart() {
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Type');
  data.addColumn('number', 'Count');
  Object.keys(real_data).forEach(function(key) {
    data.addRow([key, real_data[key]]);
  });
  var options = {
    title: 'Certificate Stats',
    chartArea: {
      bottom: 40
    },
    hAxis: {
      title: 'Type',
      textStyle: {
        fontSize: 8,
        fontStyle: "Arial"
      }
    },
    vAxis: {
      title: 'Count'
    }
  };
  var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
  chart.draw(data, options);
}

function drawPieChart() {
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Type');
  data.addColumn('number', 'Count');
  Object.keys(real_data).forEach(function(key) {
    data.addRow([key, real_data[key]]);
  });
  var options = {
    title: 'Certificate Stats',
    is3D: true,
    pieSliceTextStyle: {
      fontSize: 8
    }
  };
  var chart = new google.visualization.PieChart(document.getElementById('piechart'));
  chart.draw(data, options);
}

2. 修正Bootstrap布局结构

调整表单区域的嵌套,用row包裹表单组,确保栅格布局符合Bootstrap规范,避免样式冲突。

修改后的HTML代码:

<div class="col-md-6">
  <h2>Certificates Report using Google Chart</h2>
  <div id="certificate-container">
    <!-- 用row包裹表单,确保栅格布局正确 -->
    <div class="row">
      <div class="form-group col-md-4">
        <label for="days_cert">Interval:</label>
        <select name="days" id="days_cert" class="form-control table-filter">
          <option value="1">1 day ago</option>
          <option value="7">7 days ago</option>
          <option value="30">1 month ago</option>
          <option value="90">3 month ago</option>
          <option value="365" selected>1 year ago</option>
          <option value="730">2 year ago</option>
        </select>
      </div>
    </div>
    <div id="chart-container">
      <div id="chart_div"></div>
      <div id="piechart" style="width: 500px; height: 300px;"></div>
    </div>
  </div>
</div>

修改说明

  • 移除了重复的google.charts.load()调用,避免DOM重置导致下拉框消失。
  • 将图表绘制逻辑绑定到AJAX请求的成功回调,确保数据更新后再渲染图表,解决时序问题。
  • 修正Bootstrap栅格嵌套,避免图表渲染时破坏表单区域的布局。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 00:42:23