Flask渲染模板丢失JS动态生成HTML的解决方案问询
解决方案
方案一:后端渲染时重建动态输入框
核心思路是把用户动态添加的输入框数据提交给后端,后端保存后,在渲染模板时根据这些数据重新生成对应的输入框,页面刷新后动态输入框即可保留。
1. 调整前端模板结构
修改输入框命名为数组形式(quantities[]),方便后端批量接收数据;同时用Jinja2语法在模板中循环生成历史输入框:
<div class="col-12" id="InputRows"> <!-- 初始输入框 --> <div class="input-row row"> <div class="col-xl-4 offset-xl-0"><label>Quantity</label></div> <div class="col-xl-4 offset-xl-1"> <input type="number" name="quantities[]" value="{{ quantity_return[0] if quantity_return else '' }}" required> </div> <div class="col-xl-2"> <button type="button" onclick="addInputRow()">添加输入框</button> </div> </div> <!-- 渲染历史动态输入框 --> {% if quantity_return and quantity_return|length > 1 %} {% for qty in quantity_return[1:] %} <div class="input-row row"> <div class="col-xl-4 offset-xl-0"><label>Quantity</label></div> <div class="col-xl-4 offset-xl-1"> <input type="number" name="quantities[]" value="{{ qty }}" required> </div> <div class="col-xl-2"> <button type="button" onclick="removeInputRow(this)">删除</button> </div> </div> {% endfor %} {% endif %} </div>
2. 编写动态增删输入框的JS
// 添加新输入框 function addInputRow() { const container = document.getElementById('InputRows'); const newRow = document.createElement('div'); newRow.className = 'input-row row'; newRow.innerHTML = ` <div class="col-xl-4 offset-xl-0"><label>Quantity</label></div> <div class="col-xl-4 offset-xl-1"> <input type="number" name="quantities[]" required> </div> <div class="col-xl-2"> <button type="button" onclick="removeInputRow(this)">删除</button> </div> `; container.appendChild(newRow); } // 删除输入框 function removeInputRow(btn) { btn.closest('.input-row').remove(); }
3. 修改Flask后端代码
接收所有输入值并传递回模板:
from flask import Flask, request, render_template app = Flask(__name__) @app.route('/') def index(): return render_template('template.html', quantity_return=[]) @app.route("/CalculateMaths", methods=['POST']) def CalculateMaths(): if request.method == 'POST': # 获取所有数量输入值,返回列表 quantities = request.form.getlist('quantities[]') # 这里可添加自定义计算逻辑 # ... # 将所有输入值传递回模板,用于重建输入框 return render_template("template.html", quantity_return=quantities) if __name__ == '__main__': app.run(debug=True)
方案二:AJAX异步提交表单(无页面刷新)
通过JS异步提交表单,不刷新整个页面,动态输入框会直接保留,仅更新计算结果区域。
1. 调整前端表单与结果展示区
<form id="mathForm"> <div class="col-12" id="InputRows"> <div class="input-row row"> <div class="col-xl-4 offset-xl-0"><label>Quantity</label></div> <div class="col-xl-4 offset-xl-1"> <input type="number" name="quantities[]" required> </div> <div class="col-xl-2"> <button type="button" onclick="addInputRow()">添加输入框</button> </div> </div> </div> <div class="mt-3"> <button type="submit">提交计算</button> </div> </form> <!-- 计算结果展示区 --> <div id="resultArea" class="mt-3"></div>
2. 编写AJAX提交逻辑
// 阻止表单默认提交,改用AJAX document.getElementById('mathForm').addEventListener('submit', function(e) { e.preventDefault(); const formData = new FormData(this); fetch('/CalculateMaths', { method: 'POST', body: formData }) .then(response => response.text()) .then(data => { // 更新结果区域 document.getElementById('resultArea').innerHTML = `计算结果:${data}`; }) .catch(error => { document.getElementById('resultArea').innerHTML = '提交出错,请重试'; }); }); // 动态增删输入框函数同方案一 function addInputRow() { const container = document.getElementById('InputRows'); const newRow = document.createElement('div'); newRow.className = 'input-row row'; newRow.innerHTML = ` <div class="col-xl-4 offset-xl-0"><label>Quantity</label></div> <div class="col-xl-4 offset-xl-1"> <input type="number" name="quantities[]" required> </div> <div class="col-xl-2"> <button type="button" onclick="removeInputRow(this)">删除</button> </div> `; container.appendChild(newRow); } function removeInputRow(btn) { btn.closest('.input-row').remove(); }
3. 修改Flask后端代码
直接返回计算结果而非渲染模板:
from flask import Flask, request, render_template, Response app = Flask(__name__) @app.route('/') def index(): return render_template('template.html') @app.route("/CalculateMaths", methods=['POST']) def CalculateMaths(): if request.method == 'POST': quantities = request.form.getlist('quantities[]') # 示例计算:求和 total = sum(int(qty) for qty in quantities if qty.isdigit()) return Response(str(total), mimetype='text/plain') if __name__ == '__main__': app.run(debug=True)
内容的提问来源于stack exchange,提问作者KurtEdw
相关产品推荐
相关产品推荐

