使用热线(Flask 应用程序)刷新 html 页面的(可变)部分

Refresh (variable) part of an html page with hotwire (Flask app)


上下文

我正在使用 SQLAchemy 数据库构建一个简单的“todo”flask 应用程序。 任务按部分排序(查看下图以了解其组织方式)。

一旦我实现了我想要的所有功能,我 运行 进入了整个页面的问题 每次触发按钮时都会刷新 (add/edit/delete/update_status)。 然后我发现 hotwire 可以很好地处理这个问题。

这是我的 taskManager.html 组织:

<!--New task button-->
<turbo-frame id="data_frame-add">
<button class="btn-add" onclick="openAddForm()">...</button>
<div class="form-popup" id="myForm">
    <form name="AddTaskForm" action="{{ url_for('add_task') }}" class="form-container" method="POST">
        <label for="section"><b>Section</b></label>
        <input type="text" id="section" name="section" required>
        <label for="content"><b>Task</b></label>
        <input type="text" id="content" name="content required>
        <button type="submit" class="btn">Add</button>
    </form>
</div>
</turbo-frame>

<!--Display sections and tasks-->
<div class="flex-row">
    {% for section in sections %}
        <turbo-frame id="data_frame-{{ section }}">
            <div class="flex-column">
                <h2>{{ section }}</h2>
                {% for task in tasks %}
                    {% if task.section == section %}
                        <p>{{ task }}</p>
                        <button class="satus"></button>
                        <button class="edit"></button>
                        <div class="form-popup" id="form-{{ task.id }}">...</div>
                        <button class="delete"></button>
                        <div class="form-popup" id="form-{{ task.id }}">...</div>
                    {% endif %}
                {% endfor %}
            </div>
        </turbo-frame>
    {% endfor %}
</div>

使用 ID 为 data_frame-{{ section }} 的 Turbo 框架(每个部分一个)允许在点击 statusedit[ 时仅刷新相关部分=84=] 和 删除 按钮(例如,点击 第 2 节 任务 2 的删除按钮只会刷新 turbo 帧 data_frame-Section 2)。然而,由于 新任务 按钮不在这些 turbo 帧中,它的工作方式不同,这是一个不同的挑战...


问题

添加新任务时,我希望将任务的部分(在此处输入<input type="text" id="section" name="section"...>)保存在一个变量中,该变量将用于定位一个特定的 <turbo-frame id="data_frame-{{ section }}"> 并刷新它而不刷新整个页面。 目前,由于 New task 按钮被 <turbo-frame id="data_frame-add"> 包裹着,它是自包含的(这意味着如果我将任务 5 添加到第 1 部分,则只有 ID 为 data_frame-add 刷新的不是 data_frame-Section 1 所以我需要手动刷新页面才能看到变化)


我试过的

我在表格中添加了data-turbo-frame

<form name="AddTaskForm" action="{{ url_for('add_task') }}" class="form-container" method="POST" data-turbo-frame="data_frame-Section 1">

为了能够在 Section 1 部分添加新任务时刷新 "data_frame-Section 1",它成功了!但是我想用 <section> 使这个 data-turbo-frame="data_frame-<section>" 成为一个获得 <input type="text" id="section" name="section"...>

值的变量

为了实现这一点,我删除了 data-turbo-frame="data_frame-Section 1" 的形式:

<form name="AddTaskForm" action="{{ url_for('add_task') }}" class="form-container" method="POST">

并添加了 Javascript 部分:

var sectionValVar = document.getElementById("section").value;
const sectionValPref = "data_frame-";
let sectionVal = sectionValPref + sectionValVar;
$(".AddTaskForm").attr("data-turbo-frame", sectionVal);

sectionVal 应该获取变量值 "data_frame-<section>" 并且最后一行将 "data-turbo-frame" = "data_frame-<section>" 添加到 <form name="AddTaskForm"...>

但这不起作用。我不确定这是否有可能实现,因为它看起来很棘手...... 但是,如果有人对此有任何提示或修复,那就太棒了!

谢谢!


其他资源

这是我的 python flask 应用程序中的 add_task 路线:

@app.route('/add', methods=['GET', 'POST'])
def add_task():
content = request.form.get('content')
section = request.form.get('section')
task = Task(content=content, section=section)
db.session.add(task)
db.session.commit()
return redirect(url_for('taskManager'))

这看起来可行,但我没有看到事件侦听器在输入值更改时设置表单 data-turbo-frame 属性。 您需要在表单提交之前或输入更新时更新属性。

这就是您使用 jquery

可以做到的
$("#section").change(function() {
   let sectionAndPrefix = "data_frame-" + $("#section").val()
   $(".AddTaskForm").attr("data-turbo-frame", sectionAndPrefix);
})

香草味javascript

const sectionInput = document.querySelector("#section")
sectionInput.addEventListener("input", function() {
  const taskForm = document.querySelector(".AddTaskForm")
  const sectionAndPrefix = "data_frame-" + sectionInput.value
  taskForm.setAttribute("data-turbo-frame", sectionAndPrefix)
})