基于Flask/Python/Bootstrap实现客户端交互式关联表格
客户端实现交互式联动表格方案
完全可以在客户端实现这个需求——一次性把所有租金和付款数据加载到页面,通过JavaScript监听行选中事件,实时过滤付款表格内容,全程无需额外请求后端。
实现步骤
1. Flask后端准备数据
在视图函数中,把租金和付款的数据集一次性传给前端模板:
from flask import Flask, render_template app = Flask(__name__) # 模拟业务数据,实际可从数据库/其他数据源获取 def get_rents_data(): return [ {"id": 1, "tenant": "张三", "amount": 3000, "month": "2024-01"}, {"id": 2, "tenant": "李四", "amount": 2800, "month": "2024-01"}, {"id": 3, "tenant": "王五", "amount": 3200, "month": "2024-01"} ] def get_payments_data(): return [ {"id": 1, "rent_id": 1, "payment_date": "2024-01-05", "amount": 3000}, {"id": 2, "rent_id": 1, "payment_date": "2024-01-20", "amount": 0}, {"id": 3, "rent_id": 2, "payment_date": "2024-01-03", "amount": 2800}, {"id": 4, "rent_id": 3, "payment_date": "2024-01-08", "amount": 3200} ] @app.route('/') def index(): rents = get_rents_data() payments = get_payments_data() return render_template('index.html', rents=rents, payments=payments) if __name__ == '__main__': app.run(debug=True)
2. HTML模板(结合Bootstrap)
用Bootstrap做表格样式,渲染后端传入的数据,同时添加JavaScript实现联动逻辑:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>租金-付款联动表格</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container mt-4"> <div class="row"> <!-- 租金表格 --> <div class="col-md-6"> <h3>Rents(租金)</h3> <table class="table table-striped table-hover" id="rentsTable"> <thead> <tr> <th>ID</th> <th>租户</th> <th>金额</th> <th>月份</th> </tr> </thead> <tbody> {% for rent in rents %} <tr data-rent-id="{{ rent.id }}"> <td>{{ rent.id }}</td> <td>{{ rent.tenant }}</td> <td>{{ rent.amount }}</td> <td>{{ rent.month }}</td> </tr> {% endfor %} </tbody> </table> </div> <!-- 付款表格 --> <div class="col-md-6"> <h3>Payments(付款)</h3> <table class="table table-striped table-hover" id="paymentsTable"> <thead> <tr> <th>ID</th> <th>对应租金ID</th> <th>付款日期</th> <th>付款金额</th> </tr> </thead> <tbody id="paymentsBody"> {% for payment in payments %} <tr data-rent-id="{{ payment.rent_id }}"> <td>{{ payment.id }}</td> <td>{{ payment.rent_id }}</td> <td>{{ payment.payment_date }}</td> <td>{{ payment.amount }}</td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> <script> // 将后端传入的付款数据转为JS数组 const allPayments = [ {% for payment in payments %} {id: {{ payment.id }}, rentId: {{ payment.rent_id }}, paymentDate: "{{ payment.payment_date }}", amount: {{ payment.amount }}}, {% endfor %} ]; const rentsTable = document.getElementById('rentsTable'); const paymentsBody = document.getElementById('paymentsBody'); // 监听租金表格行点击事件 rentsTable.addEventListener('click', function(e) { const row = e.target.closest('tr'); if (!row || row.tagName !== 'TR') return; // 移除所有行的选中样式,给当前行添加高亮 document.querySelectorAll('#rentsTable tr').forEach(r => r.classList.remove('table-primary')); row.classList.add('table-primary'); const rentId = parseInt(row.dataset.rentId); // 过滤对应租金ID的付款数据 const filteredPayments = allPayments.filter(p => p.rentId === rentId); // 更新付款表格内容 renderPayments(filteredPayments); }); // 渲染付款表格的工具函数 function renderPayments(payments) { let html = ''; if (payments.length === 0) { html = '<tr><td colspan="4" class="text-center">暂无对应付款数据</td></tr>'; } else { payments.forEach(p => { html += ` <tr> <td>${p.id}</td> <td>${p.rentId}</td> <td>${p.paymentDate}</td> <td>${p.amount}</td> </tr> `; }); } paymentsBody.innerHTML = html; } // 可选:默认选中第一行租金 // const firstRow = document.querySelector('#rentsTable tr:not(:first-child)'); // if (firstRow) firstRow.click(); </script> </body> </html>
核心逻辑说明
- 数据预加载:后端一次性传递全量数据到前端,避免后续请求
- 行标识存储:通过
data-rent-id属性绑定租金ID,点击时快速获取 - 客户端过滤:用JavaScript数组的
filter方法筛选数据,实时渲染表格 - 视觉反馈:给选中行添加
table-primary类,明确当前选中状态
内容的提问来源于stack exchange,提问作者OcMaRUS
相关产品推荐
相关产品推荐

