Search code examples
ajaxdjangodjango-bootstrap3

Django, submiting a form via AJAX


I have seen answers (here and here) for similar questions, but none of them work in my case. I have a simple form in a template, I am using bootstrap for rendering.

Once I submit the form, the response is rendered directly in the browser. When I return to the previous page (with the browser's button) then the success part of the AJAX call is executed.

forms.py

class QueryForm(forms.Form):
    query = forms.CharField(label='Discover something', max_length=256)

views.py

def query_view(request, id):
    if request.method == 'POST':
        # Just for testing, send True
        response_data = {
            'result': True
        }

        return HttpResponse(json.dumps(response_data), content_type="application/json")
    else:
        try:
            # Create a form and send it to the template
            query_form = QueryForm()

            return render(request, 'query_template.html', {'query_form': query_form})
        except ObjectDoesNotExist:
            return render(request, 'error.html')

urls.py

urlpatterns = [
    url(r'^query', views.query_view, name='query_view'),
    url(r'^', views.home, name='home'),
]

query_template.html

{% extends 'base.html' %}

{% load static %}
{% load bootstrap3 %}

{% block content %}

    {# Display a form #}
    <form method="post" class="form">
        {% csrf_token %}
        {% bootstrap_form query_form %}
        {% buttons %}
            <button class="btn btn-primary" id="query-button">
                {% bootstrap_icon "star" %} Submit
            </button>
        {% endbuttons %}
    </form>
    <ul id="result"></ul>

    <script src="{% static 'scripts/main.js' %}"></script>
{% endblock %}

main.js

$('#query-button').click(function (event) {
    $.ajax({
        url: "/query/",
        type: "POST",
        data: {},
        cache: false,

        // handle a successful response
        success: function (json) {
            console.log(json); // log the returned json to the console
            $("#result").html("<li>" + json.result + "</li>");
            console.log("success"); // another sanity check
        },

        // handle a non-successful response
        error: function (xhr, errmsg, err) {
            console.log(xhr.status + ": " + xhr.responseText);
        }
    });
});

// It also includes functions to manage the CRFS token

I have been playing with the code. If instead a form I use <input> and <button id='query-button'> it renders the response without reloading the page.


Solution

  • You need to prevent the default submit action of the HTML form, via event.preventDefault().