Python Flask应用结合JavaScript实现下拉选项表格多列筛选
多下拉菜单联合筛选表格实现方案
核心需求
- 选中国家下拉菜单选项时,自动过滤表格中国家字段匹配的所有行
- 支持多列配置多个下拉菜单,实现多条件联合筛选
- 兼容现有Flask+原生JS技术栈,无需引入第三方依赖
原有问题点
之前使用addEventListener('click')绑定下拉菜单交互无法实现完整功能,核心原因是下拉框的click事件会在点击展开选项列表时就触发,此时用户还未选中目标选项,拿不到正确的筛选值,应该绑定change事件,仅当选中值发生变化时执行筛选逻辑。
现有代码基础
Flask后端代码
app = Flask(__name__) test_data = [['jack', 23, 'china', 'https://www.google.com'], ['jill', 22, 'canada', 'https://www.cnn.com'], ['john', 24, 'canada', 'https://www.cnn.com'], ['jane', 30, 'australia', 'https://www.bbc.com']] test_df = pd.DataFrame(test_data, columns=['name', 'age', 'country', 'link']) test_df = test_df.to_dict(orient='index') @app.route("/hello") def index(): return render_template("index.html", test_df=test_df)
HTML模板结构
<div class="container"> <label for="country">Countries</label> <form class="form"> <div class="form__group"> <select id="country" name="country" data-dropdown> <option value="">Please select a country</option> <option value="australia">Australia</option> <option value="canada">Canada</option> <option value="china">China</option> </select> </div> </form> </div> <table class="table"> <tbody id="myTable"> </tbody> </table>
初始JS逻辑
var mydata = JSON.parse('{{ test_df|tojson }}'); var countrySelector = document.getElementById('country'); // but what next? buildTable(mydata) function buildTable(data) { var table = document.getElementById('myTable') table.innerHTML = '' for (var key in data) { var row = `<tr> <td>${data[key].name}</td> <td>${data[key].age}</td> <td><a href="${data[key].link}" target='_blank'>${data[key].country}</a></td> </tr>` table.innerHTML += row } }
实现方案
核心逻辑
- 单独存储后端返回的全量原始数据,所有筛选操作都基于这份原始数据执行,避免多次筛选后数据丢失
- 统一给所有带
data-dropdown标识的下拉框绑定change事件,任意下拉框值变化时触发筛选 - 每次筛选时先收集所有已选中的有效筛选条件,再遍历原始数据匹配全部条件,最终用匹配结果重新渲染表格
- 逻辑天然支持扩展,后续新增筛选下拉框无需修改JS代码,只要按规则配置HTML属性即可自动接入联合筛选
修改后完整JS代码
// 存储全量原始数据,作为筛选的数据源 const originalData = JSON.parse('{{ test_df|tojson }}'); // 首次加载渲染全量数据 buildTable(Object.values(originalData)); // 给所有标记了data-dropdown的筛选下拉框绑定change事件 document.querySelectorAll('[data-dropdown]').forEach(selector => { selector.addEventListener('change', applyFilters); }); // 筛选执行函数 function applyFilters() { // 收集当前所有生效的筛选条件:键为对应数据字段名,值为选中的筛选值 const activeFilters = {}; document.querySelectorAll('[data-dropdown]').forEach(selector => { const matchField = selector.name; const selectedVal = selector.value.trim(); if (selectedVal) activeFilters[matchField] = selectedVal; }); // 遍历原始数据,匹配所有生效筛选条件 const filteredResult = Object.values(originalData).filter(item => { return Object.entries(activeFilters).every(([field, filterVal]) => { // 统一转小写匹配,避免大小写差异导致匹配失败 return String(item[field]).toLowerCase() === filterVal.toLowerCase(); }); }); // 用筛选结果重新渲染表格 buildTable(filteredResult); } // 表格渲染函数 function buildTable(data) { const table = document.getElementById('myTable'); table.innerHTML = ''; data.forEach(row => { const rowHtml = `<tr> <td>${row.name}</td> <td>${row.age}</td> <td><a href="${row.link}" target='_blank'>${row.country}</a></td> </tr>`; table.innerHTML += rowHtml; }); }
多列筛选扩展方法
后续需要新增其他字段的筛选下拉框时,不需要修改任何JS逻辑,只要在HTML中新增对应select标签,满足两个规则即可自动接入联合筛选:
- 给
select标签添加data-dropdown属性 - 给
select标签设置name属性,属性值和数据中对应字段名完全一致
示例:新增年龄筛选下拉框代码
<div class="form__group"> <label for="age">Age</label> <select id="age" name="age" data-dropdown> <option value="">Please select age</option> <option value="22">22</option> <option value="23">23</option> <option value="24">24</option> <option value="30">30</option> </select> </div>
可选优化
- 如果需要支持模糊匹配,只需要把筛选判断逻辑从全等判断改为包含判断即可:
return String(item[field]).toLowerCase().includes(filterVal.toLowerCase()); - 如果需要支持范围筛选(比如年龄区间),只需要在
applyFilters函数里扩展对应字段的匹配逻辑即可
内容的提问来源于stack exchange,提问作者kodikai
相关产品推荐
相关产品推荐

