Here is the answer to my question which makes a form submission targeting several DOM elements using Turbo-Streams (no need to use Turbo-Frames).
Considering I have a main view function called Main
in my Flask app:
@app.route('/')
def Main():
...
return render_template('base.html', contents=contents)
With base.html:
<form name="AddContentForm" action="{{ url_for('add_content') }}" method="POST">
<input type="text" list="sectionList" id="section" name="section">
<datalist id="sectionList">
{% for content in contents %}
<option value="{{ content }}">
{% endfor %}
</datalist>
<button type="submit" onclick="submitForm()">Add</button>
</form>
<div id="contents">
{% for content in contents %}
<div class="flex-column">
<p>>{{ content }}</p>
</div>
{% endfor %}
</div>
In order to reload only specific targeted parts of the html page when adding new content I had to modify the add_content
function in the Flask app.
Instead of redirecting toward the main view function (which reloads the whole page):
@app.route('/add', methods=['POST'])
def add_content():
...
return redirect('/')
I returned a Turbo-Streams element:
@app.route('/add', methods=['POST'])
def add_content():
...
sectionListHtml = render_template("sectionList.html", contents=contents)
contentsHtml = render_template("contents.html", contents=contents)
return turbo.stream([
turbo.update(sectionListHtml, target="sectionList"),
turbo.update(contentsHtml, target="contents")
])
with sectionList.html:
{% for content in contents %}
<option value="{{ content }}">
{% endfor %}
and contents.html:
{% for content in contents %}
<div class="flex-column">
<p>>{{ content }}</p>
</div>
{% endfor %}
Complementary informations
initialization of the python Flask app with Turbo:
from flask import Flask, render_template, request, url_for, redirect
from turbo_flask import Turbo
app = Flask(__name__)
turbo = Turbo(app)
Thank you again for your help @tleish !