背景:在web开发中,有时候我们希望网页上的几个下拉列表框之间的数据有前后关联的关系,比如一个省市选择的系统,有两个下拉列表框,一个选择省份,一个选择城市,省份的列表中列举了全国所有的省,但是如果我们在选择城市的时候,下拉列表中传递的是全国所有的城市,那么我们要从全国所有的城市中取选择对应省份的城市,无异于大海捞针,所以希望可以实现如果我选择了山东省,那么城市列表中传递的城市都是山东省的城市。
实现:
基于上述背景,我在网上搜索了一些资料,但是全部都是由前端写死的一些数据,每个下拉列表并不能动态的从数据库中拉取,所以非常不实用。
下面我通过两个ajax请求实现了三个下拉列表的联动。
先讲一下思路:
首先第一级下拉列表是通过后端返回的数据直接加载页面渲染出来的结果
然后是第二级下拉列表,通过选择一级列表后,确定了一级列表被选中的值A,然后发起一个ajax请求,这个请求中携带了一级列表的选中值A,然后后端捕获了这个请求之后,将相应的参数解析出来,从数据库中查询与A值相关的二级列表的所有项目,并返回,然后前端操作返回值显示到二级列表中。
最后三级列表同理。
前端html代码(这里只列出最顶级列表框渲染代码):
<div class="form-group has-success">
<label for="project" class="col-md-2 control-label text-info" style="font-size: 14px;">项目:</label>
<div class="col-md-4">
<select id="project" name="project" class="form-control" οnchange="selectProject()"> //select控件添加onchange事件
{% for foo in project %} //逐条插入后端数据库查询返回的结果
<option value={{ foo.project_name }}>{{ foo.project_name }}</option>
{% endfor %}
</select>
</div>
</div>
具体前端js代码:
<script>
function selectProject() {
var projectName;
var data;
var username = $("#case_user").val();
var project = document.getElementById("project");
$("#module").html(""); //每次重新选择当前列表框,就清空下一级列表框。
for (i=0;i<project.length;i++){
if (project[i].selected == true){ //判断被选中项
projectName = project[i].text;
data = {
'project':projectName,
};
$.ajax({ //发起ajax请求
type:'post',
url:'/api/'+username+'/project_selector/',
data:JSON.stringify(data),
contentType:'application/json',
success:function (data) { //后端返回数据,是列表形式的
if (data){
for (i=0;i<data.length;i++){
$("<option value='"+data[i]+"'>" + data[i] + "</option>").appendTo('#module'); //将后端返回的数据逐项插入到下一级列表框中
}
}
else {
pass;
}
}
});
}
}
}
</script>
需要补充的地方
后端路由函数返回的数据库结果列表,在return时有可能会出错“TypeError: 'list' object is not callable”,这里需要通过jsonify处理下
from flask import jsonify
return jsonify(result)