Reputation: 1059
I'm trying to create a CRUD page using django + HTMX and unable to send POST request. hx-post sends a GET request instead of POST request.
my Role Models is as follows:
class Role(models.Model):
name = models.CharField(max_length=200)
I'm creating the form using Cripsy Forms as follows
class RoleForm(forms.ModelForm):
class Meta:
model = Role
fields = ('name', )
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.fields['name'].label = "Role"
self.helper.add_input(Submit('add_new_Role', 'Add', css_class='role_button'))
self.helper.layout = Layout(
Row(
Column('name'),
)
)
I'm using the form in my template like this :
{% extends 'main.html' %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row">
<div class="card col-md-6 ml-auto mr-auto">
<div class="card-body">
{% crispy role_form %}
</div>
</div>
</div>
<div id="role_list">
{% include 'role_list.html' %}
</div>
{% endblock %}
{% block javascript %}
<script type="text/javascript">
$(document).ready(function(){
$("form").removeAttr("method");
$('.role_button').attr("hx-post", '{% url "role_add" %}');
$('.role_button').attr('hx-target', '#role_list');
});
</script>
{% endblock %}
The CDN link is added in the main.html file.
My understanding is that clicking the ADD button should trigger a POST request. However GET request is initiated, which makes me feel like the HTMX part did not work at all
Upvotes: 3
Views: 9383
Reputation: 99
@Mark said in his answer Here my way to type the HTMX code in crispy-forms.
<form class="form-inline"
hx-get = "{% url 'myurl' %}"
hx-target="#myinclude"
>
{{ form|crispy }}
<button type="submit" class="btn btn-success"
>Search</button>
</form>
Typing the code in the <button hx-get....htmx ajax call doesn't work. If you want to see some code example and tutorial about HTMX Pandas and Crispy working together here my own page to find them Htmx django-filter Pandas and Crispy form
Upvotes: 0
Reputation: 2539
As @Mark said in his answer, I would suggest to define form tag on your template and put htmx
stuff onto that:
<form hx-post={% url 'submit url' %} <!-- Do not set action and method -->
...other htmx attributes>
{% crispy form %}
</form>
and set your form helper to doesn't render a form tag
self.helper.form_tag = False
And by the way, if you've set htmx to send csrf
automatically, (See here for more info) It's better to disable csrf
in your form helper as well
self.helper.disable_csrf = True # no need, request is sent via htmx
Upvotes: 1
Reputation: 200486
The typical way to do this is to add the hx-post
and hx-target
attributes to the form
element, not the submit
button. This will cause HTMX to intercept the submit event on the form, and submit the entire form as an AJAX request.
See the Triggering Requests documentation:
By default, AJAX requests are triggered by the "natural" event of an element:
- form is triggered on the submit event
Upvotes: 1
Reputation: 1059
I found the solution after a too many trial and errors.
Turns out Django Crispy forms create an input with type='submit'
to create the submit button
however, hx-post works only if you have a button with type='submit'
instead of input in order to submit the form
Upvotes: 0