mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 07:31:07 -05:00
7.2 KiB
7.2 KiB
HTMX Best Practices and Advanced Techniques
Research Summary
Comprehensive research from HTMX documentation and Django-specific patterns to inform the ThrillWiki frontend redesign.
Core HTMX Patterns for Implementation
1. Essential UI Patterns
Active Search Pattern
<input type="search" name="q" placeholder="Search..."
hx-get="/search"
hx-trigger="input changed delay:250ms"
hx-target="#results">
<div id="results"></div>
Application: Enhance park and ride search functionality with real-time results.
Click to Edit Pattern
<div hx-target="this" hx-swap="outerHTML">
<span id="name">World</span>
<button hx-get="/names/1" hx-target="closest div">Edit</button>
</div>
Application: Inline editing for park details, ride information.
Infinite Scroll Pattern
<div id="content">
<!-- Initial content here -->
</div>
<div hx-trigger="revealed" hx-get="/more-content" hx-swap="beforeend" hx-target="#content">
Loading...
</div>
Application: Park and ride listings with progressive loading.
Lazy Loading Pattern
<div hx-trigger="intersect" hx-get="/lazy-content" hx-swap="innerHTML">
Loading...
</div>
Application: Photo galleries, detailed ride statistics.
2. Form Handling Patterns
Inline Validation Pattern
<form hx-post="/contact">
<input type="email" id="email" name="email" required
hx-trigger="input changed delay:500ms"
hx-post="/validate-email"
hx-target="#email-error">
<span id="email-error" class="error"></span>
</form>
Application: Real-time validation for park creation, ride submission forms.
Bulk Update Pattern
<form hx-put="/names">
<input type="hidden" name="_method" value="PUT">
<table class="table">
<tbody>
<tr>
<td><input class="form-check-input" type="checkbox" name="ids[]" value="1">
<td><input type="text" name="names[]" value="Alice">
</tr>
</tbody>
</table>
<button>Update Selected</button>
</form>
Application: Batch operations for moderation, bulk park updates.
3. Advanced Interaction Patterns
Progress Bar Pattern
<div class="progress">
<div id="progress-bar" class="progress-bar" style="width: 0%;">0%</div>
</div>
<button hx-post="/run-job"
hx-target="#progress-bar"
hx-swap="innerHTML">Run Job</button>
Application: Photo upload progress, data import operations.
Modal Dialog Pattern
<button hx-get="/modal/content" hx-target="#modal-container" hx-swap="innerHTML">Open Modal</button>
<div id="modal-container"></div>
Application: Park creation forms, ride detail modals, photo viewers.
Value Select Pattern (Dependent Dropdowns)
<select name="country" hx-get="/states" hx-target="#state-select">
<option value="US">United States</option>
<option value="CA">Canada</option>
</select>
<select id="state-select" name="state">
<option value="">Please select a state</option>
</select>
Application: Location selection (Country -> State -> City), park filtering.
Django-Specific HTMX Patterns
1. Form Validation with Django
HTMX Form Validation Decorator
def htmx_form_validate(*, form_class: type):
def decorator(view_func):
@wraps(view_func)
def wrapper(request, *args, **kwargs):
if (
request.method == "GET"
and "Hx-Request" in request.headers
and (htmx_validation_field := request.GET.get("_validate_field", None))
):
form = form_class(request.GET)
form.is_valid() # trigger validation
return HttpResponse(render_single_field_row(form, htmx_validation_field))
return view_func(request, *args, **kwargs)
return wrapper
return decorator
Template Integration
<div
class="field is-horizontal {{ classes }}"
id="form-row-{{ field.name }}"
hx-get="."
hx-vals='{"_validate_field": "{{ field.name }}" }'
hx-trigger="focusout from:#form-row-{{ field.name }}"
hx-include="#form-row-{{ field.name }}"
hx-target="this"
hx-ext="morph"
hx-swap="morph:outerHTML"
>
2. Django View Patterns
Block-Based Partial Rendering
@for_htmx(use_block_from_params=True)
def monster_detail(request: HttpRequest, monster_id: int):
monster = get_object_or_404(Monster.objects.all(), id=monster_id)
if request.method == "POST":
if "kick" in request.POST:
monster.kick()
elif "hug" in request.POST:
monster.hug()
if not is_htmx(request):
return HttpResponseRedirect("")
return TemplateResponse(request, "monster_detail.html", {"monster": monster})
Modal Form Handling
form = CreateMonsterForm(request.POST)
if form.is_valid():
monster = form.save()
return HttpResponse(
headers={
"Hx-Trigger": json.dumps({
"closeModal": True,
"monsterCreated": monster.id,
})
}
)
3. Template Organization
Inline Partials Pattern
{% block monster-form %}
<form
method="POST"
action=""
id="monster-form"
hx-post=""
hx-target="#monster-form"
hx-swap="outerHTML"
hx-vals='{"use_block": "monster-form"}'
>
{% csrf_token %}
<!-- Form content -->
</form>
{% endblock %}
Performance Optimizations
1. Request Optimization
- Use
hx-trigger="input changed delay:500ms"for debounced search - Implement
hx-push-url="true"for browser history management - Use
hx-swap="morph:outerHTML"for efficient DOM updates
2. Loading States
- Implement loading indicators with
htmx-indicatorclass - Use skeleton screens for better perceived performance
- Add progress bars for long-running operations
3. Error Handling
- Implement comprehensive error responses
- Use
hx-confirmfor destructive actions - Provide clear user feedback for all operations
Integration with Alpine.js
Complementary Usage
<div x-data="{ count: 0 }">
<button hx-post="/increment"
hx-target="#count-display"
hx-swap="innerHTML"
@click="count++">
Increment
</button>
<span id="count-display" x-text="'Count: ' + count">Count: 0</span>
</div>
Event Coordination
- Use HTMX for server communication
- Use Alpine.js for client-side state management
- Coordinate between both using custom events
Implementation Priorities for ThrillWiki
High Priority
- Active Search: Real-time park and ride search
- Inline Validation: Form validation with immediate feedback
- Click to Edit: Inline editing for park/ride details
- Modal Dialogs: Form submissions and detail views
Medium Priority
- Infinite Scroll: Progressive loading for large lists
- Bulk Operations: Moderation and batch updates
- Progress Indicators: File uploads and data operations
- Dependent Dropdowns: Location and category selection
Low Priority
- Advanced Animations: Smooth transitions between states
- Real-time Updates: Live notifications and updates
- Offline Support: Progressive web app features