Skip to content

Instantly share code, notes, and snippets.

@bennettscience
Last active June 21, 2022 12:36
Show Gist options
  • Save bennettscience/85a70b3a1fd90eaed08dfd24d7311e2f to your computer and use it in GitHub Desktop.
Save bennettscience/85a70b3a1fd90eaed08dfd24d7311e2f to your computer and use it in GitHub Desktop.
An HTMX-based dynamic form system
# other flask stuff - this is just an example
# The actual application uses blueprints to keep routes organized.
from flask import Blueprint, Flask
app = Flask(__name__)
course_blueprint = Blueprint('courses', __name__)
app.register_blueprint(course_blueprint)
# Get the form to edit the event
@course_blueprint.get("/courses/<int:event_id>/edit")
def edit_event(event_id):
event = Course.query.get(event_id)
if event is None:
abort(404)
# Get the locations and course types
locations = Location.query.all()
course_types = CourseType.query.all()
content = {
"event": event,
"locations": locations,
"course_types": course_types
}
# In the return, define send the wrapper template and define
# a partial to render _inside_.
return render_template(
'shared/partials/sidebar.html',
partial='admin/forms/edit-event.html',
**content
)
# Handle the submit in the same blueprint
@course_blueprint.put("/courses/<int:event_id>/edit")
def update_event(event_id):
# do stuff
pass
<form
hx-put="/courses/{{event.id}}"
hx-trigger="request"
hx-swap="innerHTML"
hx-target="#course-data--result"
hx-ext="new-event"
hx-indicator="#toast"
>
<p>Editing <b>{{event.title}}</b></p>
<label>
<p>Edit title</p>
<input type="text" name="title" id="" value="{{event.title}}" />
</label>
<label>
<p>Edit description</p>
<textarea name="description" id="" cols="30" rows="10">
{{event.description}}
</textarea>
</label>
<label>
<p>Edit start date</p>
<input
_="
on load
call shiftISOTime({{event.starts}})
then set @value to the result
"
type="datetime-local"
name="starts"
id=""
value=""
/>
</label>
<label for="">
<p>Edit end date</p>
<input
type="datetime-local"
name="ends"
id=""
value=""
/>
</label>
<label for="">
<p>Edit max size</p>
<input
type="number"
name="course_size"
id=""
value="{{event.course_size}}"
/>
</label>
<label>
<p>Edit event type</p>
<select name="coursetype_id">
{% for option in event_types %}
<option value="{{option.value}}">{{option.text}}</option>
{% endfor %}
</select>
</label>
<label>
<p>Edit location</p>
<select name="location_id">
{% for option in locations %}
<option value="{{option.value}}">{{option.text}}</option>
{% endfor %}
</select>
</label>
<button
type="submit"
class="btn btn--primary"
_="on click trigger request add @disabled"
>
Submit
</button>
</form>
<!--
The sidebar wrapper expects:
- A partial element to render in the container
- An event object
- Additional data
- Any necessary icons for the display
If the keys are missing, they will be ignored in the final render.
-->
<!-- This uses _hyperscript to handle minor frontend scripting -->
<section
_="on closeSidebar
add .hide to me
then wait 1s
then remove me
end
"
id="right-sidebar"
class="sidebar sidebar--right {{'hide' if hide}}"
>
<div id="right-sidebar-inner">
<button class="btn--close" _="on click trigger closeSidebar">
× close
</button>
{{ render_partial(partial, event=event, locations=locations, course_types=course_types)}}
</div>
</section>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment