I'm encountering an issue when trying to send two values from the frontend to the backend using htmx. Here's my code:
{% include "base.html" %}
{% block content %}
<div class='flex flex-col h-screen w-screen overflow-y-hidden'>
{% include "sidebar.html" %}
<div class='h-full flex items-center justify-center'>
<div class='w-4/5 max-h-screen h-4/5 border border-black flex flex-col overflow-x-hidden overflow-y-scroll mb-12'>
<!-- Form Data -->
{% for field, value in data.items %}
<div class='w-full h-28 p-1 m-5 flex flex-col mx-24'>
<label for="{{ field }}" class="block mb-2 text-sm font-medium text-gray-900">{{ field }}</label>
<input type="hidden" name="field" value="{{ field }}">
<input type="text" name="value" value="{{ value }}"
class="editable-field bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-3/4 p-2.5"
hx-trigger="blur" hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'form' formId %}"
hx-vals='{"field": "{{ field }}", "value": "{{ value }}"}'>
</div>
{% endfor %}
<!-- End form data -->
</div>
</div>
</div>
{% endblock content %}
I've tried using hx-vals and included quotes for those values, but the backend only receives the value, not the field. Here's the output in the backend:
<QueryDict: {'value': ['valiue']}>
valiue None
In my view, I'm attempting to retrieve both values using the following code:
def post(self, request, formId):
print(request.POST)
field = request.POST.get('field')
value = request.POST.get('value')
print(value, field)
I've tried using hx-vals, and changing the value of the input to the field property (removing it), and that works, but it's not a feasible solution for my scenario. I noticed that in the payload, the field is not present, leading me to believe that only the value of the input is being sent, and the hx-vals property is being ignored.
Is there a way to send both the field and value using htmx, or do I need to explore alternative approaches? Any guidance would be appreciated
Solved, Use the hx-focusout and add a form tag, I avoided the form tag as I had a misconception that it required a button with the type of submit, here's the code which is working
{% include "base.html" %}
{% block content %}
<div class='flex flex-col h-screen w-screen overflow-y-hidden'>
{% include "sidebar.html" %}
<div class='h-full flex items-center justify-center'>
<div class='w-4/5 max-h-screen h-4/5 border border-black flex flex-col overflow-x-hidden overflow-y-scroll mb-12'>
<!--Form Data-->
{% for field, value in data.items %}
<div class='w-full h-28 p-1 m-5 flex flex-col mx-24'>
<form hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-trigger="focusout" hx-post="{% url 'form' formId %}">
<label for="{{ field }}" class="block mb-2 text-sm font-medium text-gray-900">{{ field }}</label>
<input type="hidden" name="field" value="{{ field }}">
<input type="text" name="value" value="{{ value }}"
class="editable-field bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-3/4 p-2.5" >
</form>
</div>
{% endfor %}
<!--End form data -->
</div>
</div>
</div>
{% endblock content %}
the hx-blur only sends the value inside the input and not on the form, but triggering the form using focusout sends the data in both inputs to the backend