模态框内Chosen下拉框数据库加载异常及样式丢失问题排查
问题描述
在Bootstrap模态框中使用Chosen jQuery插件实现下拉框数据加载(数据来自SQL数据库),遇到以下异常:
- 全屏打开模态框时,下拉框无法加载数据
- 缩小窗口分辨率后,下拉框虽能显示结果,但无法展开选项列表,且插件样式丢失
怀疑Chosen插件与Bootstrap存在冲突。
问题截图1:全屏状态下下拉框无数据
问题截图2:窗口缩小后下拉框样式异常,无法展开选项
相关代码
HTML
<div class="row"> <div class="col-md-6 col-sm-3 col-lg-5 form-group"> <label class="col-form-label col-md-4 col-sm-2 label-align mr-n1" for="codix">De <i class="fa fa-user"></i></label> <datalist id="nombresb"> @@BENEF@@ </datalist> <input type="text" id="buscab2" class="form-control" placeholder="" list="nombresb"> </div> <div class="col-md-6 col-sm-6 col-lg-5 form-group"> <label class="col-form-label col-md-4 col-sm-2 label-align" for="descx">Para <i class="fa fa-users"></i></label> <select name="acompanantes" id="acompanantes2" multiple class="locales" data-placeholder="Para"> <option value=""></option> {{empleado}} </select> </div> </div>
PHP(查询指定Memo数据)
function buscaMemoPorID(){ $soloID = $_POST["idMemo"]; $query = " SELECT TB_Memo.ID_Memo, TB_Memo.Fecha_Creacion, a.Nombres +' '+ a.Apellidos as Destinatarios, b.Nombres + ' ' + b.Apellidos as Remitente, TB_Memo.Asunto, TB_Memo.Contenido, TB_Memo.ID_TipoMemo, TB_Memo.ID_EstadoMemo, TB_Memo.Fecha_Envio, c.Descripcion, TB_Memo.ID_Memorandum, TB_Destinatario.ID_Empleado as Para from TB_Memo inner join TB_Destinatario on TB_Memo.ID_Memo = TB_Destinatario.ID_Memo inner join TB_Remitente on TB_Memo.ID_Memo = TB_Remitente.ID_Memo inner join [IHTT_RRHH].[dbo].[TB_Empleados] a on TB_Destinatario.ID_Empleado = a.ID_Empleado inner join [IHTT_RRHH].[dbo].[TB_Empleados] b on TB_Remitente.ID_Empleado = b.ID_Empleado left outer join [IHTT_MEMORANDUM].[dbo].[TB_EstadoDestinatario] c on TB_Memo.ID_EstadoDestinatario = c.ID_EstadoDestinatario Where TB_Memo.ID_Memo = $soloID"; $p = array(); $data = $this->select($query, $p ); $datos[1]=count($data); $datos[0]=array(); for($i=0; $i<count($data); $i++){ $datos[0][$i] = array("ult" =>1, "num" =>$data[$i]["ID_Memo"], "nome"=>$data[$i]["ID_Memorandum"],"tipoMe" =>$data[$i]["ID_TipoMemo"], "estaMe" =>$data[$i]["ID_EstadoMemo"], "asunto" =>$data[$i]["Asunto"], "contenido" =>$data[$i]["Contenido"], "fechEn" =>$data[$i]["Fecha_Envio"], "fechCre" =>$data[$i]["Fecha_Creacion"], "De" =>$data[$i]["Remitente"], "Para" =>$data[$i]["Para"], "estado"=>$data[$i]["Descripcion"], "Destinatarios"=>$data[$i]["Destinatarios"]); } echo json_encode($datos); }
PHP(获取员工列表)
function empleado() { $q = "SELECT [ID_Empleado] ,[Nombres] ,[Apellidos] FROM [IHTT_RRHH].[dbo].[TB_Empleados] WHERE ID_Estado = 1"; $datos = $this->select($q, array()); $opcion = ""; for ($i = 0; $i < count($datos); $i++) { $opcion .= "<option value='" .$datos[$i]["ID_Empleado"]. "'>" . utf8_encode($datos[$i]["Nombres"]) . " " . utf8_encode($datos[$i]["Apellidos"]) ."</option> "; } return $opcion; }
JS(加载指定Memo数据到模态框)
function cargaMemoEspecifico(idmemo){ var cant = $("#mostrar").val(); var form_data = new FormData(); form_data.append("action","buscaMemoPorID"); form_data.append("idMemo",idmemo); $.ajax({ url: 'api_con.php', dataType: 'json', cache: false, contentType: false, processData: false, data: form_data, type: 'post', success: function(data){ var area = data[0]; if(data[1]>0 ){ var detalle=''; var cantidad=80; var total=0; var num=1; $("#acompanantes2").html(""); for(i=0; i<area.length; i++){ let datos = tinymce.get("mensaje2").setContent(area[i].contenido); $("#modalconsulta2").modal("show"); $("#buscab2").val(area[i].De); $("#acompanantes2").append("<option value='" + area[i].Para + "'>" + area[i].Destinatarios + "</option>"); $("#modal-asunto").val(area[i].asunto); $("#modal-fecha").val(area[i].fechCre); $("#mensaje2").val(area[i].contenido); $("#idMemo").val(area[i].num); } $("#acompanantes2").trigger("chosen:updated"); } else { detalle +='<tr><td colspan="8">NO HAY DATOS EN ESTE MOMENTO.........</td></tr>'; } } }).error(function(r){ console.log("Error-->",r.responseText); }); }
解决方案
1. 调整Chosen更新时机,绑定模态框显示完成事件
Bootstrap模态框的show方法是异步的,直接在AJAX成功后触发chosen:updated时,模态框可能还未完全渲染完成,导致Chosen无法正确识别下拉框尺寸。修改JS代码,将更新操作移到模态框shown.bs.modal事件中:
function cargaMemoEspecifico(idmemo){ var cant = $("#mostrar").val(); var form_data = new FormData(); form_data.append("action","buscaMemoPorID"); form_data.append("idMemo",idmemo); $.ajax({ url: 'api_con.php', dataType: 'json', cache: false, contentType: false, processData: false, data: form_data, type: 'post', success: function(data){ var area = data[0]; if(data[1]>0 ){ $("#acompanantes2").html(""); // 先完成所有数据填充 for(i=0; i<area.length; i++){ tinymce.get("mensaje2").setContent(area[i].contenido); $("#buscab2").val(area[i].De); $("#acompanantes2").append("<option value='" + area[i].Para + "'>" + area[i].Destinatarios + "</option>"); $("#modal-asunto").val(area[i].asunto); $("#modal-fecha").val(area[i].fechCre); $("#mensaje2").val(area[i].contenido); $("#idMemo").val(area[i].num); } // 显示模态框并在完成后更新Chosen $("#modalconsulta2").modal("show").on("shown.bs.modal", function() { $("#acompanantes2").trigger("chosen:updated"); // 解绑事件避免重复触发 $(this).off("shown.bs.modal"); }); } else { detalle +='<tr><td colspan="8">NO HAY DATOS EN ESTE MOMENTO.........</td></tr>'; } } }).error(function(r){ console.log("Error-->",r.responseText); }); }
2. 提升Chosen下拉列表的z-index,避免被模态框遮挡
Bootstrap模态框默认z-index为1050,Chosen下拉框的z-index可能低于这个值导致被遮挡,添加自定义CSS:
.chosen-container-active .chosen-drop { z-index: 1060 !important; }
3. 确保Chosen初始化正确
页面加载时先初始化Chosen插件,指定宽度避免自适应异常:
$(document).ready(function() { $(".locales").chosen({ width: "100%", placeholder_text_multiple: "Para" }); });
4. 修复循环中重复显示模态框的问题
原代码中每次循环都调用$("#modalconsulta2").modal("show"),会导致模态框多次触发显示,调整为循环完成后再统一显示模态框,避免不必要的渲染冲突。
内容的提问来源于stack exchange,提问作者St3v3n
相关产品推荐
相关产品推荐

